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

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

Powered by Google App Engine
This is Rietveld 408576698