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

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

Issue 240873003: Create WebSocketTransportClientSocketPool (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add missing header includes. Fix typos. Created 6 years, 6 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_transport_client_socket_pool.h"
6
7 #include <queue>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/time/time.h"
18 #include "net/base/capturing_net_log.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/load_timing_info_test_util.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_util.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/dns/mock_host_resolver.h"
26 #include "net/socket/client_socket_handle.h"
27 #include "net/socket/client_socket_pool_histograms.h"
28 #include "net/socket/socket_test_util.h"
29 #include "net/socket/stream_socket.h"
30 #include "net/socket/transport_client_socket_pool_test_util.h"
31 #include "net/socket/websocket_endpoint_lock_manager.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 namespace net {
35
36 namespace {
37
38 const int kMaxSockets = 32;
39 const int kMaxSocketsPerGroup = 6;
40 const net::RequestPriority kDefaultPriority = LOW;
41
42 // RunLoop doesn't support this natively but it is easy to emulate.
43 void RunLoopForTimePeriod(base::TimeDelta period) {
44 base::RunLoop run_loop;
45 base::Closure quit_closure(run_loop.QuitClosure());
46 base::MessageLoop::current()->PostDelayedTask(
47 FROM_HERE, quit_closure, period);
48 run_loop.Run();
49 }
50
51 class WebSocketTransportClientSocketPoolTest : public testing::Test {
52 protected:
53 WebSocketTransportClientSocketPoolTest()
54 : params_(new TransportSocketParams(HostPortPair("www.google.com", 80),
55 false,
56 false,
57 OnHostResolutionCallback())),
58 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
59 host_resolver_(new MockHostResolver),
60 client_socket_factory_(&net_log_),
61 pool_(kMaxSockets,
62 kMaxSocketsPerGroup,
63 histograms_.get(),
64 host_resolver_.get(),
65 &client_socket_factory_,
66 NULL) {}
67
68 virtual ~WebSocketTransportClientSocketPoolTest() {
69 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
70 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
71 }
72
73 int StartRequest(const std::string& group_name, RequestPriority priority) {
74 scoped_refptr<TransportSocketParams> params(
75 new TransportSocketParams(HostPortPair("www.google.com", 80),
76 false,
77 false,
78 OnHostResolutionCallback()));
79 return test_base_.StartRequestUsingPool(
80 &pool_, group_name, priority, params);
81 }
82
83 int GetOrderOfRequest(size_t index) {
84 return test_base_.GetOrderOfRequest(index);
85 }
86
87 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
88 return test_base_.ReleaseOneConnection(keep_alive);
89 }
90
91 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
92 test_base_.ReleaseAllConnections(keep_alive);
93 }
94
95 TestSocketRequest* request(int i) { return test_base_.request(i); }
96
97 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
98 size_t completion_count() const { return test_base_.completion_count(); }
99
100 CapturingNetLog net_log_;
101 scoped_refptr<TransportSocketParams> params_;
102 scoped_ptr<ClientSocketPoolHistograms> histograms_;
103 scoped_ptr<MockHostResolver> host_resolver_;
104 MockTransportClientSocketFactory client_socket_factory_;
105 WebSocketTransportClientSocketPool pool_;
106 ClientSocketPoolTest test_base_;
107
108 private:
109 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest);
110 };
111
112 TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
113 TestCompletionCallback callback;
114 ClientSocketHandle handle;
115 int rv = handle.Init(
116 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
117 EXPECT_EQ(ERR_IO_PENDING, rv);
118 EXPECT_FALSE(handle.is_initialized());
119 EXPECT_FALSE(handle.socket());
120
121 EXPECT_EQ(OK, callback.WaitForResult());
122 EXPECT_TRUE(handle.is_initialized());
123 EXPECT_TRUE(handle.socket());
124 TestLoadTimingInfoConnectedNotReused(handle);
125 }
126
127 // Make sure that WebSocketTransportConnectJob passes on its priority to its
128 // HostResolver request on Init.
129 TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
130 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
131 RequestPriority priority = static_cast<RequestPriority>(i);
132 TestCompletionCallback callback;
133 ClientSocketHandle handle;
134 EXPECT_EQ(ERR_IO_PENDING,
135 handle.Init("a",
136 params_,
137 priority,
138 callback.callback(),
139 &pool_,
140 BoundNetLog()));
141 EXPECT_EQ(priority, host_resolver_->last_request_priority());
142 }
143 }
144
145 TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
146 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
147 TestCompletionCallback callback;
148 ClientSocketHandle handle;
149 HostPortPair host_port_pair("unresolvable.host.name", 80);
150 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
151 host_port_pair, false, false, OnHostResolutionCallback()));
152 EXPECT_EQ(ERR_IO_PENDING,
153 handle.Init("a",
154 dest,
155 kDefaultPriority,
156 callback.callback(),
157 &pool_,
158 BoundNetLog()));
159 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult());
160 }
161
162 TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
163 client_socket_factory_.set_client_socket_type(
164 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
165 TestCompletionCallback callback;
166 ClientSocketHandle handle;
167 EXPECT_EQ(ERR_IO_PENDING,
168 handle.Init("a",
169 params_,
170 kDefaultPriority,
171 callback.callback(),
172 &pool_,
173 BoundNetLog()));
174 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
175
176 // Make the host resolutions complete synchronously this time.
177 host_resolver_->set_synchronous_mode(true);
178 EXPECT_EQ(ERR_CONNECTION_FAILED,
179 handle.Init("a",
180 params_,
181 kDefaultPriority,
182 callback.callback(),
183 &pool_,
184 BoundNetLog()));
185 }
186
187 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
188 // First request finishes asynchronously.
189 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
190 EXPECT_EQ(OK, request(0)->WaitForResult());
191
192 // Make all subsequent host resolutions complete synchronously.
193 host_resolver_->set_synchronous_mode(true);
194
195 // Rest of them wait for the first socket to be released.
196 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
197 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
198 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
199 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
200 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
201
202 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
203
204 EXPECT_EQ(6, client_socket_factory_.allocation_count());
205
206 // One initial asynchronous request and then 5 pending requests.
207 EXPECT_EQ(6U, completion_count());
208
209 // The requests finish in FIFO order.
210 EXPECT_EQ(1, GetOrderOfRequest(1));
211 EXPECT_EQ(2, GetOrderOfRequest(2));
212 EXPECT_EQ(3, GetOrderOfRequest(3));
213 EXPECT_EQ(4, GetOrderOfRequest(4));
214 EXPECT_EQ(5, GetOrderOfRequest(5));
215 EXPECT_EQ(6, GetOrderOfRequest(6));
216
217 // Make sure we test order of all requests made.
218 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
219 }
220
221 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
222 // First request finishes asynchronously.
223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
224 EXPECT_EQ(OK, request(0)->WaitForResult());
225
226 // Make all subsequent host resolutions complete synchronously.
227 host_resolver_->set_synchronous_mode(true);
228
229 // Rest of them wait foe the first socket to be released.
230 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
231 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
232 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
234 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
235
236 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
237
238 // The pending requests should finish successfully.
239 EXPECT_EQ(OK, request(1)->WaitForResult());
240 EXPECT_EQ(OK, request(2)->WaitForResult());
241 EXPECT_EQ(OK, request(3)->WaitForResult());
242 EXPECT_EQ(OK, request(4)->WaitForResult());
243 EXPECT_EQ(OK, request(5)->WaitForResult());
244
245 EXPECT_EQ(static_cast<int>(requests()->size()),
246 client_socket_factory_.allocation_count());
247
248 // First asynchronous request, and then last 5 pending requests.
249 EXPECT_EQ(6U, completion_count());
250 }
251
252 // This test will start up a RequestSocket() and then immediately Cancel() it.
253 // The pending host resolution will eventually complete, and destroy the
254 // ClientSocketPool which will crash if the group was not cleared properly.
255 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
256 TestCompletionCallback callback;
257 ClientSocketHandle handle;
258 EXPECT_EQ(ERR_IO_PENDING,
259 handle.Init("a",
260 params_,
261 kDefaultPriority,
262 callback.callback(),
263 &pool_,
264 BoundNetLog()));
265 handle.Reset();
266 }
267
268 TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
269 ClientSocketHandle handle;
270 TestCompletionCallback callback;
271 ClientSocketHandle handle2;
272 TestCompletionCallback callback2;
273
274 EXPECT_EQ(ERR_IO_PENDING,
275 handle.Init("a",
276 params_,
277 kDefaultPriority,
278 callback.callback(),
279 &pool_,
280 BoundNetLog()));
281 EXPECT_EQ(ERR_IO_PENDING,
282 handle2.Init("a",
283 params_,
284 kDefaultPriority,
285 callback2.callback(),
286 &pool_,
287 BoundNetLog()));
288
289 handle.Reset();
290
291 EXPECT_EQ(OK, callback2.WaitForResult());
292 handle2.Reset();
293 }
294
295 TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
296 client_socket_factory_.set_client_socket_type(
297 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
298 ClientSocketHandle handle;
299 TestCompletionCallback callback;
300 EXPECT_EQ(ERR_IO_PENDING,
301 handle.Init("a",
302 params_,
303 kDefaultPriority,
304 callback.callback(),
305 &pool_,
306 BoundNetLog()));
307
308 handle.Reset();
309
310 TestCompletionCallback callback2;
311 EXPECT_EQ(ERR_IO_PENDING,
312 handle.Init("a",
313 params_,
314 kDefaultPriority,
315 callback2.callback(),
316 &pool_,
317 BoundNetLog()));
318
319 host_resolver_->set_synchronous_mode(true);
320 // At this point, handle has two ConnectingSockets out for it. Due to the
321 // setting the mock resolver into synchronous mode, the host resolution for
322 // both will return in the same loop of the MessageLoop. The client socket
323 // is a pending socket, so the Connect() will asynchronously complete on the
324 // next loop of the MessageLoop. That means that the first
325 // ConnectingSocket will enter OnIOComplete, and then the second one will.
326 // If the first one is not cancelled, it will advance the load state, and
327 // then the second one will crash.
328
329 EXPECT_EQ(OK, callback2.WaitForResult());
330 EXPECT_FALSE(callback.have_result());
331
332 handle.Reset();
333 }
334
335 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
336 // First request finishes asynchronously.
337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
338 EXPECT_EQ(OK, request(0)->WaitForResult());
339
340 // Make all subsequent host resolutions complete synchronously.
341 host_resolver_->set_synchronous_mode(true);
342
343 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
344 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
345 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
346 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
347 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
348
349 // Cancel a request.
350 const size_t index_to_cancel = 2;
351 EXPECT_FALSE(request(index_to_cancel)->handle()->is_initialized());
352 request(index_to_cancel)->handle()->Reset();
353
354 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
355
356 EXPECT_EQ(5, client_socket_factory_.allocation_count());
357
358 EXPECT_EQ(1, GetOrderOfRequest(1));
359 EXPECT_EQ(2, GetOrderOfRequest(2));
360 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
361 GetOrderOfRequest(3)); // Canceled request.
362 EXPECT_EQ(3, GetOrderOfRequest(4));
363 EXPECT_EQ(4, GetOrderOfRequest(5));
364 EXPECT_EQ(5, GetOrderOfRequest(6));
365
366 // Make sure we test order of all requests made.
367 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
368 }
369
370 class RequestSocketCallback : public TestCompletionCallbackBase {
371 public:
372 RequestSocketCallback(ClientSocketHandle* handle,
373 WebSocketTransportClientSocketPool* pool)
374 : handle_(handle),
375 pool_(pool),
376 within_callback_(false),
377 callback_(base::Bind(&RequestSocketCallback::OnComplete,
378 base::Unretained(this))) {}
379
380 virtual ~RequestSocketCallback() {}
381
382 const CompletionCallback& callback() const { return callback_; }
383
384 private:
385 void OnComplete(int result) {
386 SetResult(result);
387 ASSERT_EQ(OK, result);
388
389 if (!within_callback_) {
390 // Don't allow reuse of the socket. Disconnect it and then release it and
391 // run through the MessageLoop once to get it completely released.
392 handle_->socket()->Disconnect();
393 handle_->Reset();
394 {
395 base::MessageLoop::ScopedNestableTaskAllower allow(
396 base::MessageLoop::current());
397 base::MessageLoop::current()->RunUntilIdle();
398 }
399 within_callback_ = true;
400 scoped_refptr<TransportSocketParams> dest(
401 new TransportSocketParams(HostPortPair("www.google.com", 80),
402 false,
403 false,
404 OnHostResolutionCallback()));
405 int rv =
406 handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog());
407 EXPECT_EQ(OK, rv);
408 }
409 }
410
411 ClientSocketHandle* const handle_;
412 WebSocketTransportClientSocketPool* const pool_;
413 bool within_callback_;
414 CompletionCallback callback_;
415
416 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback);
417 };
418
419 TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
420 ClientSocketHandle handle;
421 RequestSocketCallback callback(&handle, &pool_);
422 scoped_refptr<TransportSocketParams> dest(
423 new TransportSocketParams(HostPortPair("www.google.com", 80),
424 false,
425 false,
426 OnHostResolutionCallback()));
427 int rv = handle.Init(
428 "a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog());
429 ASSERT_EQ(ERR_IO_PENDING, rv);
430
431 // The callback is going to request "www.google.com". We want it to complete
432 // synchronously this time.
433 host_resolver_->set_synchronous_mode(true);
434
435 EXPECT_EQ(OK, callback.WaitForResult());
436
437 handle.Reset();
438 }
439
440 // Make sure that pending requests get serviced after active requests get
441 // cancelled.
442 TEST_F(WebSocketTransportClientSocketPoolTest,
443 CancelActiveRequestWithPendingRequests) {
444 client_socket_factory_.set_client_socket_type(
445 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
446
447 // Queue up all the requests
448 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
449 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
450 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
451 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
452 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
453 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
454 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
455 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
456 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
457
458 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
459 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
460 for (int i = 0; i < kMaxSocketsPerGroup; i++)
461 request(i)->handle()->Reset();
462
463 // Let's wait for the rest to complete now.
464 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
465 EXPECT_EQ(OK, request(i)->WaitForResult());
466 request(i)->handle()->Reset();
467 }
468
469 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
470 }
471
472 // Make sure that pending requests get serviced after active requests fail.
473 TEST_F(WebSocketTransportClientSocketPoolTest,
474 FailingActiveRequestWithPendingRequests) {
475 client_socket_factory_.set_client_socket_type(
476 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
477
478 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
479 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
480
481 // Queue up all the requests
482 for (int i = 0; i < kNumRequests; i++)
483 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
484
485 for (int i = 0; i < kNumRequests; i++)
486 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
487 }
488
489 // The lock on the endpoint is released when a ClientSocketHandle is reset.
490 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
491 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
492 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
493 EXPECT_EQ(OK, request(0)->WaitForResult());
494 EXPECT_FALSE(request(1)->handle()->is_initialized());
495 request(0)->handle()->Reset();
496 base::RunLoop().RunUntilIdle();
497 EXPECT_TRUE(request(1)->handle()->is_initialized());
498 }
499
500 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
501 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
502 TestCompletionCallback callback;
503 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle);
504 int rv = handle->Init(
505 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
506 EXPECT_EQ(ERR_IO_PENDING, rv);
507
508 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
509 EXPECT_EQ(OK, callback.WaitForResult());
510 EXPECT_FALSE(request(0)->handle()->is_initialized());
511 handle.reset();
512 base::RunLoop().RunUntilIdle();
513 EXPECT_TRUE(request(0)->handle()->is_initialized());
514 }
515
516 // A new connection is performed when the lock on the previous connection is
517 // explicity released.
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:52 explicitly
Adam Rice 2014/06/24 06:28:38 Done.
518 TEST_F(WebSocketTransportClientSocketPoolTest,
519 ConnectionProceedsOnExplicitRelease) {
520 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
521 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
522 EXPECT_EQ(OK, request(0)->WaitForResult());
523 EXPECT_FALSE(request(1)->handle()->is_initialized());
524 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
525 base::RunLoop().RunUntilIdle();
526 EXPECT_TRUE(request(1)->handle()->is_initialized());
527 }
528
529 // A connection which is cancelled before completion does not block subsequent
530 // connections.
531 TEST_F(WebSocketTransportClientSocketPoolTest,
532 CancelDuringConnectionReleasesLock) {
533 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
534 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
535 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
536
537 client_socket_factory_.set_client_socket_types(case_types,
538 arraysize(case_types));
539
540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
542 base::RunLoop().RunUntilIdle();
543 pool_.CancelRequest("a", (request(0))->handle());
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:53 parentheses needed?
Adam Rice 2014/06/24 06:28:38 No. Removed.
544 EXPECT_EQ(OK, request(1)->WaitForResult());
545 }
546
547 // Test the case of the IPv6 address stalling, and falling back to the IPv4
548 // socket which finishes first.
549 TEST_F(WebSocketTransportClientSocketPoolTest,
550 IPv6FallbackSocketIPv4FinishesFirst) {
551 WebSocketTransportClientSocketPool pool(kMaxSockets,
552 kMaxSocketsPerGroup,
553 histograms_.get(),
554 host_resolver_.get(),
555 &client_socket_factory_,
556 NULL);
557
558 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
559 // This is the IPv6 socket.
560 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
561 // This is the IPv4 socket.
562 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
563
564 client_socket_factory_.set_client_socket_types(case_types, 2);
565
566 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:52 an IPv6 an IPv4
Adam Rice 2014/06/24 06:28:37 Done.
567 host_resolver_->rules()->AddIPLiteralRule(
568 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
569
570 TestCompletionCallback callback;
571 ClientSocketHandle handle;
572 int rv =
573 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
574 EXPECT_EQ(ERR_IO_PENDING, rv);
575 EXPECT_FALSE(handle.is_initialized());
576 EXPECT_FALSE(handle.socket());
577
578 EXPECT_EQ(OK, callback.WaitForResult());
579 EXPECT_TRUE(handle.is_initialized());
580 EXPECT_TRUE(handle.socket());
581 IPEndPoint endpoint;
582 handle.socket()->GetLocalAddress(&endpoint);
583 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
584 EXPECT_EQ(2, client_socket_factory_.allocation_count());
585 }
586
587 // Test the case of the IPv6 address being slow, thus falling back to trying to
588 // connect to the IPv4 address, but having the connect to the IPv6 address
589 // finish first.
590 TEST_F(WebSocketTransportClientSocketPoolTest,
591 IPv6FallbackSocketIPv6FinishesFirst) {
592 WebSocketTransportClientSocketPool pool(kMaxSockets,
593 kMaxSocketsPerGroup,
594 histograms_.get(),
595 host_resolver_.get(),
596 &client_socket_factory_,
597 NULL);
598
599 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
600 // This is the IPv6 socket.
601 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
602 // This is the IPv4 socket.
603 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET};
604
605 client_socket_factory_.set_client_socket_types(case_types, 2);
606 client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds(
607 TransportConnectJobHelper::kIPv6FallbackTimerInMs + 50));
608
609 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:53 an IPv6 an IPv4
Adam Rice 2014/06/24 06:28:37 Done.
610 host_resolver_->rules()->AddIPLiteralRule(
611 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
612
613 TestCompletionCallback callback;
614 ClientSocketHandle handle;
615 int rv =
616 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
617 EXPECT_EQ(ERR_IO_PENDING, rv);
618 EXPECT_FALSE(handle.is_initialized());
619 EXPECT_FALSE(handle.socket());
620
621 EXPECT_EQ(OK, callback.WaitForResult());
622 EXPECT_TRUE(handle.is_initialized());
623 EXPECT_TRUE(handle.socket());
624 IPEndPoint endpoint;
625 handle.socket()->GetLocalAddress(&endpoint);
626 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
627 EXPECT_EQ(2, client_socket_factory_.allocation_count());
628 }
629
630 TEST_F(WebSocketTransportClientSocketPoolTest,
631 IPv6NoIPv4AddressesToFallbackTo) {
632 WebSocketTransportClientSocketPool pool(kMaxSockets,
633 kMaxSocketsPerGroup,
634 histograms_.get(),
635 host_resolver_.get(),
636 &client_socket_factory_,
637 NULL);
638
639 client_socket_factory_.set_client_socket_type(
640 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
641
642 // Resolve an AddressList with only IPv6 addresses.
643 host_resolver_->rules()->AddIPLiteralRule(
644 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
645
646 TestCompletionCallback callback;
647 ClientSocketHandle handle;
648 int rv =
649 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
650 EXPECT_EQ(ERR_IO_PENDING, rv);
651 EXPECT_FALSE(handle.is_initialized());
652 EXPECT_FALSE(handle.socket());
653
654 EXPECT_EQ(OK, callback.WaitForResult());
655 EXPECT_TRUE(handle.is_initialized());
656 EXPECT_TRUE(handle.socket());
657 IPEndPoint endpoint;
658 handle.socket()->GetLocalAddress(&endpoint);
659 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
660 EXPECT_EQ(1, client_socket_factory_.allocation_count());
661 }
662
663 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
664 WebSocketTransportClientSocketPool pool(kMaxSockets,
665 kMaxSocketsPerGroup,
666 histograms_.get(),
667 host_resolver_.get(),
668 &client_socket_factory_,
669 NULL);
670
671 client_socket_factory_.set_client_socket_type(
672 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
673
674 // Resolve an AddressList with only IPv4 addresses.
675 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
676
677 TestCompletionCallback callback;
678 ClientSocketHandle handle;
679 int rv =
680 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
681 EXPECT_EQ(ERR_IO_PENDING, rv);
682 EXPECT_FALSE(handle.is_initialized());
683 EXPECT_FALSE(handle.socket());
684
685 EXPECT_EQ(OK, callback.WaitForResult());
686 EXPECT_TRUE(handle.is_initialized());
687 EXPECT_TRUE(handle.socket());
688 IPEndPoint endpoint;
689 handle.socket()->GetLocalAddress(&endpoint);
690 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
691 EXPECT_EQ(1, client_socket_factory_.allocation_count());
692 }
693
694 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
695 // proceeed immediately.
696 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
697 WebSocketTransportClientSocketPool pool(kMaxSockets,
698 kMaxSocketsPerGroup,
699 histograms_.get(),
700 host_resolver_.get(),
701 &client_socket_factory_,
702 NULL);
703
704 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
705 // First IPv6 socket.
706 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
707 // Second IPv6 socket.
708 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
709 // This is the IPv4 socket.
710 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET};
711
712 client_socket_factory_.set_client_socket_types(case_types,
713 arraysize(case_types));
714
715 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
716 host_resolver_->rules()->AddIPLiteralRule(
717 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
718 host_resolver_->set_synchronous_mode(true);
719 TestCompletionCallback callback;
720 ClientSocketHandle handle;
721 int rv =
722 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
723 EXPECT_EQ(OK, rv);
724 ASSERT_TRUE(handle.socket());
725
726 IPEndPoint endpoint;
727 handle.socket()->GetPeerAddress(&endpoint);
728 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
729 }
730
731 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
732 // connections proceed immediately.
733 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
734 WebSocketTransportClientSocketPool pool(kMaxSockets,
735 kMaxSocketsPerGroup,
736 histograms_.get(),
737 host_resolver_.get(),
738 &client_socket_factory_,
739 NULL);
740
741 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
742 // First IPv6 socket.
743 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
744 // Second IPv6 socket.
745 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
746 // This is the IPv4 socket.
747 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET};
748
749 client_socket_factory_.set_client_socket_types(case_types,
750 arraysize(case_types));
751
752 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
753 host_resolver_->rules()->AddIPLiteralRule(
754 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
755
756 TestCompletionCallback callback;
757 ClientSocketHandle handle;
758 int rv =
759 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
760 EXPECT_EQ(ERR_IO_PENDING, rv);
761 EXPECT_FALSE(handle.socket());
762
763 base::Time start(base::Time::NowFromSystemTime());
764 EXPECT_EQ(OK, callback.WaitForResult());
765 EXPECT_LT(base::Time::NowFromSystemTime() - start,
766 base::TimeDelta::FromMilliseconds(
767 TransportConnectJobHelper::kIPv6FallbackTimerInMs));
768 ASSERT_TRUE(handle.socket());
769
770 IPEndPoint endpoint;
771 handle.socket()->GetPeerAddress(&endpoint);
772 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
773 }
774
775 // If two sockets connect successfully, the one which connected first wins (this
776 // can only happen if the sockets are different types, since sockets of the same
777 // type do not race).
778 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
779 WebSocketTransportClientSocketPool pool(kMaxSockets,
780 kMaxSocketsPerGroup,
781 histograms_.get(),
782 host_resolver_.get(),
783 &client_socket_factory_,
784 NULL);
785
786 client_socket_factory_.set_client_socket_type(
787 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
788
789 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
790 host_resolver_->rules()->AddIPLiteralRule(
791 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
792
793 TestCompletionCallback callback;
794 ClientSocketHandle handle;
795 int rv =
796 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
797 EXPECT_EQ(ERR_IO_PENDING, rv);
798 ASSERT_FALSE(handle.socket());
799
800 base::Closure ipv6_connect_trigger =
801 client_socket_factory_.WaitForTriggerableSocketCreation();
802 base::Closure ipv4_connect_trigger =
803 client_socket_factory_.WaitForTriggerableSocketCreation();
804
805 ipv4_connect_trigger.Run();
806 ipv6_connect_trigger.Run();
807
808 EXPECT_EQ(OK, callback.WaitForResult());
809 ASSERT_TRUE(handle.socket());
810
811 IPEndPoint endpoint;
812 handle.socket()->GetPeerAddress(&endpoint);
813 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
814 }
815
816 // We should not report failure until all connections have failed.
817 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
818 WebSocketTransportClientSocketPool pool(kMaxSockets,
819 kMaxSocketsPerGroup,
820 histograms_.get(),
821 host_resolver_.get(),
822 &client_socket_factory_,
823 NULL);
824
825 client_socket_factory_.set_client_socket_type(
826 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
827 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
828 TransportConnectJobHelper::kIPv6FallbackTimerInMs / 3);
829 client_socket_factory_.set_delay(delay);
830
831 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 address.
832 host_resolver_->rules()->AddIPLiteralRule("*",
833 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
834 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
835 "1.1.1.1,2.2.2.2",
836 std::string());
837
838 // Expected order of events:
839 // After 100ms: Connect to 1:abcd::3:4:ff times out
840 // After 200ms: Connect to 2:abcd::3:4:ff times out
841 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
842 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
843 // After 500ms: Connect to 2.2.2.2 times out
844
845 TestCompletionCallback callback;
846 ClientSocketHandle handle;
847 base::Time start(base::Time::NowFromSystemTime());
848 int rv =
849 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
850 EXPECT_EQ(ERR_IO_PENDING, rv);
851
852 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
853
854 EXPECT_GE(base::Time::NowFromSystemTime() - start, delay * 5);
855 }
856
857 // Global timeout for all connects applies. This test is disabled by default
858 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
859 // want to run it.
860 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
861 WebSocketTransportClientSocketPool pool(kMaxSockets,
862 kMaxSocketsPerGroup,
863 histograms_.get(),
864 host_resolver_.get(),
865 &client_socket_factory_,
866 NULL);
867 const base::TimeDelta connect_job_timeout = pool.ConnectionTimeout();
868
869 client_socket_factory_.set_client_socket_type(
870 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
871 client_socket_factory_.set_delay(base::TimeDelta::FromSeconds(1) +
872 connect_job_timeout / 6);
873
874 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 address.
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:53 addresses
Adam Rice 2014/06/24 06:28:38 Done.
875 host_resolver_->rules()->AddIPLiteralRule("*",
876 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
877 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
878 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
879 "1.1.1.1,2.2.2.2,3.3.3.3,"
880 "4.4.4.4,5.5.5.5,6.6.6.6",
881 std::string());
882
883 TestCompletionCallback callback;
884 ClientSocketHandle handle;
885
886 int rv =
887 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
888 EXPECT_EQ(ERR_IO_PENDING, rv);
889
890 EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult());
891 }
892
893 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) {
894 host_resolver_->set_synchronous_mode(true);
895 for (int i = 0; i < kMaxSockets; ++i) {
896 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
897 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
898 }
899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
900 }
901
902 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
903 for (int i = 0; i < kMaxSockets + 1; ++i) {
904 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
905 }
906 // Now there are 32 sockets waiting to connect, and one stalled.
907 for (int i = 0; i < kMaxSockets; ++i) {
908 base::RunLoop().RunUntilIdle();
909 EXPECT_TRUE(request(i)->handle()->is_initialized());
910 EXPECT_TRUE(request(i)->handle()->socket());
911 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
912 }
913 // Now there are 32 sockets connected, and one stalled.
914 base::RunLoop().RunUntilIdle();
915 EXPECT_FALSE(request(kMaxSockets)->handle()->is_initialized());
916 EXPECT_FALSE(request(kMaxSockets)->handle()->socket());
917 }
918
919 TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) {
920 host_resolver_->set_synchronous_mode(true);
921 for (int i = 0; i < kMaxSockets; ++i) {
922 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
923 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
924 }
925
926 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
927 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
928 EXPECT_TRUE(request(kMaxSockets)->handle()->is_initialized());
929 EXPECT_TRUE(request(kMaxSockets)->handle()->socket());
930 }
931
932 TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) {
933 for (int i = 0; i < kMaxSockets + 1; ++i) {
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
935 }
936 EXPECT_EQ(OK, request(0)->WaitForResult());
937 EXPECT_TRUE(pool_.IsStalled());
938 }
939
940 TEST_F(WebSocketTransportClientSocketPoolTest,
941 CancellingPendingSocketUnstallsStalledSocket) {
942 for (int i = 0; i < kMaxSockets + 1; ++i) {
943 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
944 }
945 EXPECT_EQ(OK, request(0)->WaitForResult());
946 request(1)->handle()->Reset();
947 base::RunLoop().RunUntilIdle();
948 EXPECT_FALSE(pool_.IsStalled());
949 }
950
951 TEST_F(WebSocketTransportClientSocketPoolTest,
952 LoadStateOfStalledSocketIsWaitingForAvailableSocket) {
953 for (int i = 0; i < kMaxSockets + 1; ++i) {
954 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
955 }
956 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
957 pool_.GetLoadState("a", request(kMaxSockets)->handle()));
958 }
959
960 TEST_F(WebSocketTransportClientSocketPoolTest,
961 CancellingStalledSocketUnstallsPool) {
962 for (int i = 0; i < kMaxSockets + 1; ++i) {
963 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
964 }
965 request(kMaxSockets)->handle()->Reset();
966 EXPECT_FALSE(pool_.IsStalled());
967 }
968
969 TEST_F(WebSocketTransportClientSocketPoolTest,
970 FlushWithErrorFlushesPendingConnections) {
971 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
972 pool_.FlushWithError(ERR_FAILED);
973 EXPECT_EQ(ERR_FAILED, request(0)->WaitForResult());
974 }
975
976 TEST_F(WebSocketTransportClientSocketPoolTest,
977 FlushWithErrorFlushesStalledConnections) {
978 for (int i = 0; i < kMaxSockets + 1; ++i) {
979 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
980 }
981 pool_.FlushWithError(ERR_FAILED);
982 EXPECT_EQ(ERR_FAILED, request(kMaxSockets)->WaitForResult());
983 }
984
985 TEST_F(WebSocketTransportClientSocketPoolTest,
986 AfterFlushWithErrorCanMakeNewConnections) {
987 for (int i = 0; i < kMaxSockets + 1; ++i) {
988 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
989 }
990 pool_.FlushWithError(ERR_FAILED);
991 host_resolver_->set_synchronous_mode(true);
992 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
993 }
994
995 // Deleting pending connections can release the lock on the endpoint, which can
996 // in principle lead to other pending connections succeeding. However, when we
997 // call FlushWithError(), everything should fail.
998 TEST_F(WebSocketTransportClientSocketPoolTest,
999 FlushWithErrorDoesNotCauseSuccessfulConnections) {
1000 host_resolver_->set_synchronous_mode(true);
1001 MockTransportClientSocketFactory::ClientSocketType first_type[] = {
1002 // First socket
1003 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
1004 };
1005 client_socket_factory_.set_client_socket_types(first_type,
1006 arraysize(first_type));
1007 // The rest of the sockets will connect synchronously.
1008 client_socket_factory_.set_client_socket_type(
tyoshino (SeeGerritForStatus) 2014/06/24 05:46:53 you might want to name this set_default_client_soc
Adam Rice 2014/06/24 06:28:38 That makes sense. But it affects the TransportClie
1009 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
1010 for (int i = 0; i < kMaxSockets; ++i) {
1011 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1012 }
1013 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in
1014 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the
1015 // lock, they will synchronously connect.
1016 pool_.FlushWithError(ERR_FAILED);
1017 for (int i = 0; i < kMaxSockets; ++i) {
1018 EXPECT_EQ(ERR_FAILED, request(i)->WaitForResult());
1019 }
1020 }
1021
1022 // This is a regression test for the first attempted fix for
1023 // FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can
1024 // have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for
1025 // the lock at the same time.
1026 TEST_F(WebSocketTransportClientSocketPoolTest,
1027 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes) {
1028 host_resolver_->set_synchronous_mode(true);
1029 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have
1030 // one IPv4.
1031 std::vector<MockTransportClientSocketFactory::ClientSocketType> socket_types(
1032 kMaxSockets + 1,
1033 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET);
1034 client_socket_factory_.set_client_socket_types(&socket_types[0],
1035 socket_types.size());
1036 // The rest of the sockets will connect synchronously.
1037 client_socket_factory_.set_client_socket_type(
1038 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET);
1039 for (int i = 0; i < kMaxSockets; ++i) {
1040 host_resolver_->rules()->ClearRules();
1041 // Each connect job has a different IPv6 address but the same IPv4 address.
1042 // So the IPv6 connections happen in parallel but the IPv4 ones are
1043 // serialised.
1044 host_resolver_->rules()->AddIPLiteralRule("*",
1045 base::StringPrintf(
1046 "%x:abcd::3:4:ff,"
1047 "1.1.1.1",
1048 i + 1),
1049 std::string());
1050 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1051 }
1052 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
1053 // are started yet.
1054 RunLoopForTimePeriod(base::TimeDelta::FromMilliseconds(
1055 TransportConnectJobHelper::kIPv6FallbackTimerInMs));
1056 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
1057 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
1058 pool_.FlushWithError(ERR_FAILED);
1059 for (int i = 0; i < kMaxSockets; ++i) {
1060 EXPECT_EQ(ERR_FAILED, request(i)->WaitForResult());
1061 }
1062 }
1063
1064 } // namespace
1065
1066 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/websocket_transport_client_socket_pool.cc ('k') | net/socket/websocket_transport_connect_sub_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698