1 // Copyright (c) 2011 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/transport_client_socket_pool.h"
6
7 #include "base/callback.h"
8 #include "base/compiler_specific.h"
9 #include "base/logging.h"
10 #include "base/message_loop.h"
11 #include "base/threading/platform_thread.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/mock_host_resolver.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_util.h"
16 #include "net/base/sys_addrinfo.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/socket/client_socket.h"
19 #include "net/socket/client_socket_factory.h"
20 #include "net/socket/client_socket_handle.h"
21 #include "net/socket/client_socket_pool_histograms.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/socket/ssl_host_info.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace net {
27
28 using internal::ClientSocketPoolBaseHelper;
29
30 namespace {
31
32 const int kMaxSockets = 32;
33 const int kMaxSocketsPerGroup = 6;
34 const net::RequestPriority kDefaultPriority = LOW;
35
SetIPv4Address(IPEndPoint * address)36 void SetIPv4Address(IPEndPoint* address) {
37 IPAddressNumber number;
38 CHECK(ParseIPLiteralToNumber("1.1.1.1", &number));
39 *address = IPEndPoint(number, 80);
40 }
41
SetIPv6Address(IPEndPoint * address)42 void SetIPv6Address(IPEndPoint* address) {
43 IPAddressNumber number;
44 CHECK(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
45 *address = IPEndPoint(number, 80);
46 }
47
48 class MockClientSocket : public ClientSocket {
49 public:
MockClientSocket(const AddressList & addrlist)50 MockClientSocket(const AddressList& addrlist)
51 : connected_(false),
52 addrlist_(addrlist) {}
53
54 // ClientSocket methods:
Connect(CompletionCallback * callback)55 virtual int Connect(CompletionCallback* callback) {
56 connected_ = true;
57 return OK;
58 }
Disconnect()59 virtual void Disconnect() {
60 connected_ = false;
61 }
IsConnected() const62 virtual bool IsConnected() const {
63 return connected_;
64 }
IsConnectedAndIdle() const65 virtual bool IsConnectedAndIdle() const {
66 return connected_;
67 }
GetPeerAddress(AddressList * address) const68 virtual int GetPeerAddress(AddressList* address) const {
69 return ERR_UNEXPECTED;
70 }
GetLocalAddress(IPEndPoint * address) const71 virtual int GetLocalAddress(IPEndPoint* address) const {
72 if (!connected_)
73 return ERR_SOCKET_NOT_CONNECTED;
74 if (addrlist_.head()->ai_family == AF_INET)
75 SetIPv4Address(address);
76 else
77 SetIPv6Address(address);
78 return OK;
79 }
NetLog() const80 virtual const BoundNetLog& NetLog() const {
81 return net_log_;
82 }
83
SetSubresourceSpeculation()84 virtual void SetSubresourceSpeculation() {}
SetOmniboxSpeculation()85 virtual void SetOmniboxSpeculation() {}
WasEverUsed() const86 virtual bool WasEverUsed() const { return false; }
UsingTCPFastOpen() const87 virtual bool UsingTCPFastOpen() const { return false; }
88
89 // Socket methods:
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)90 virtual int Read(IOBuffer* buf, int buf_len,
91 CompletionCallback* callback) {
92 return ERR_FAILED;
93 }
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)94 virtual int Write(IOBuffer* buf, int buf_len,
95 CompletionCallback* callback) {
96 return ERR_FAILED;
97 }
SetReceiveBufferSize(int32 size)98 virtual bool SetReceiveBufferSize(int32 size) { return true; }
SetSendBufferSize(int32 size)99 virtual bool SetSendBufferSize(int32 size) { return true; }
100
101 private:
102 bool connected_;
103 const AddressList addrlist_;
104 BoundNetLog net_log_;
105 };
106
107 class MockFailingClientSocket : public ClientSocket {
108 public:
MockFailingClientSocket(const AddressList & addrlist)109 MockFailingClientSocket(const AddressList& addrlist) : addrlist_(addrlist) {}
110
111 // ClientSocket methods:
Connect(CompletionCallback * callback)112 virtual int Connect(CompletionCallback* callback) {
113 return ERR_CONNECTION_FAILED;
114 }
115
Disconnect()116 virtual void Disconnect() {}
117
IsConnected() const118 virtual bool IsConnected() const {
119 return false;
120 }
IsConnectedAndIdle() const121 virtual bool IsConnectedAndIdle() const {
122 return false;
123 }
GetPeerAddress(AddressList * address) const124 virtual int GetPeerAddress(AddressList* address) const {
125 return ERR_UNEXPECTED;
126 }
GetLocalAddress(IPEndPoint * address) const127 virtual int GetLocalAddress(IPEndPoint* address) const {
128 return ERR_UNEXPECTED;
129 }
NetLog() const130 virtual const BoundNetLog& NetLog() const {
131 return net_log_;
132 }
133
SetSubresourceSpeculation()134 virtual void SetSubresourceSpeculation() {}
SetOmniboxSpeculation()135 virtual void SetOmniboxSpeculation() {}
WasEverUsed() const136 virtual bool WasEverUsed() const { return false; }
UsingTCPFastOpen() const137 virtual bool UsingTCPFastOpen() const { return false; }
138
139 // Socket methods:
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)140 virtual int Read(IOBuffer* buf, int buf_len,
141 CompletionCallback* callback) {
142 return ERR_FAILED;
143 }
144
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)145 virtual int Write(IOBuffer* buf, int buf_len,
146 CompletionCallback* callback) {
147 return ERR_FAILED;
148 }
SetReceiveBufferSize(int32 size)149 virtual bool SetReceiveBufferSize(int32 size) { return true; }
SetSendBufferSize(int32 size)150 virtual bool SetSendBufferSize(int32 size) { return true; }
151
152 private:
153 const AddressList addrlist_;
154 BoundNetLog net_log_;
155 };
156
157 class MockPendingClientSocket : public ClientSocket {
158 public:
159 // |should_connect| indicates whether the socket should successfully complete
160 // or fail.
161 // |should_stall| indicates that this socket should never connect.
162 // |delay_ms| is the delay, in milliseconds, before simulating a connect.
MockPendingClientSocket(const AddressList & addrlist,bool should_connect,bool should_stall,int delay_ms)163 MockPendingClientSocket(
164 const AddressList& addrlist,
165 bool should_connect,
166 bool should_stall,
167 int delay_ms)
168 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
169 should_connect_(should_connect),
170 should_stall_(should_stall),
171 delay_ms_(delay_ms),
172 is_connected_(false),
173 addrlist_(addrlist) {}
174
175 // ClientSocket methods:
Connect(CompletionCallback * callback)176 virtual int Connect(CompletionCallback* callback) {
177 MessageLoop::current()->PostDelayedTask(
178 FROM_HERE,
179 method_factory_.NewRunnableMethod(
180 &MockPendingClientSocket::DoCallback, callback), delay_ms_);
181 return ERR_IO_PENDING;
182 }
183
Disconnect()184 virtual void Disconnect() {}
185
IsConnected() const186 virtual bool IsConnected() const {
187 return is_connected_;
188 }
IsConnectedAndIdle() const189 virtual bool IsConnectedAndIdle() const {
190 return is_connected_;
191 }
GetPeerAddress(AddressList * address) const192 virtual int GetPeerAddress(AddressList* address) const {
193 return ERR_UNEXPECTED;
194 }
GetLocalAddress(IPEndPoint * address) const195 virtual int GetLocalAddress(IPEndPoint* address) const {
196 if (!is_connected_)
197 return ERR_SOCKET_NOT_CONNECTED;
198 if (addrlist_.head()->ai_family == AF_INET)
199 SetIPv4Address(address);
200 else
201 SetIPv6Address(address);
202 return OK;
203 }
NetLog() const204 virtual const BoundNetLog& NetLog() const {
205 return net_log_;
206 }
207
SetSubresourceSpeculation()208 virtual void SetSubresourceSpeculation() {}
SetOmniboxSpeculation()209 virtual void SetOmniboxSpeculation() {}
WasEverUsed() const210 virtual bool WasEverUsed() const { return false; }
UsingTCPFastOpen() const211 virtual bool UsingTCPFastOpen() const { return false; }
212
213 // Socket methods:
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)214 virtual int Read(IOBuffer* buf, int buf_len,
215 CompletionCallback* callback) {
216 return ERR_FAILED;
217 }
218
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)219 virtual int Write(IOBuffer* buf, int buf_len,
220 CompletionCallback* callback) {
221 return ERR_FAILED;
222 }
SetReceiveBufferSize(int32 size)223 virtual bool SetReceiveBufferSize(int32 size) { return true; }
SetSendBufferSize(int32 size)224 virtual bool SetSendBufferSize(int32 size) { return true; }
225
226 private:
DoCallback(CompletionCallback * callback)227 void DoCallback(CompletionCallback* callback) {
228 if (should_stall_)
229 return;
230
231 if (should_connect_) {
232 is_connected_ = true;
233 callback->Run(OK);
234 } else {
235 is_connected_ = false;
236 callback->Run(ERR_CONNECTION_FAILED);
237 }
238 }
239
240 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_;
241 bool should_connect_;
242 bool should_stall_;
243 int delay_ms_;
244 bool is_connected_;
245 const AddressList addrlist_;
246 BoundNetLog net_log_;
247 };
248
249 class MockClientSocketFactory : public ClientSocketFactory {
250 public:
251 enum ClientSocketType {
252 MOCK_CLIENT_SOCKET,
253 MOCK_FAILING_CLIENT_SOCKET,
254 MOCK_PENDING_CLIENT_SOCKET,
255 MOCK_PENDING_FAILING_CLIENT_SOCKET,
256 // A delayed socket will pause before connecting through the message loop.
257 MOCK_DELAYED_CLIENT_SOCKET,
258 // A stalled socket that never connects at all.
259 MOCK_STALLED_CLIENT_SOCKET,
260 };
261
MockClientSocketFactory()262 MockClientSocketFactory()
263 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET),
264 client_socket_types_(NULL), client_socket_index_(0),
265 client_socket_index_max_(0),
266 delay_ms_(ClientSocketPool::kMaxConnectRetryIntervalMs) {}
267
CreateTransportClientSocket(const AddressList & addresses,NetLog *,const NetLog::Source &)268 virtual ClientSocket* CreateTransportClientSocket(
269 const AddressList& addresses,
270 NetLog* /* net_log */,
271 const NetLog::Source& /* source */) {
272 allocation_count_++;
273
274 ClientSocketType type = client_socket_type_;
275 if (client_socket_types_ &&
276 client_socket_index_ < client_socket_index_max_) {
277 type = client_socket_types_[client_socket_index_++];
278 }
279
280 switch (type) {
281 case MOCK_CLIENT_SOCKET:
282 return new MockClientSocket(addresses);
283 case MOCK_FAILING_CLIENT_SOCKET:
284 return new MockFailingClientSocket(addresses);
285 case MOCK_PENDING_CLIENT_SOCKET:
286 return new MockPendingClientSocket(addresses, true, false, 0);
287 case MOCK_PENDING_FAILING_CLIENT_SOCKET:
288 return new MockPendingClientSocket(addresses, false, false, 0);
289 case MOCK_DELAYED_CLIENT_SOCKET:
290 return new MockPendingClientSocket(addresses, true, false, delay_ms_);
291 case MOCK_STALLED_CLIENT_SOCKET:
292 return new MockPendingClientSocket(addresses, true, true, 0);
293 default:
294 NOTREACHED();
295 return new MockClientSocket(addresses);
296 }
297 }
298
CreateSSLClientSocket(ClientSocketHandle * transport_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config,SSLHostInfo * ssl_host_info,CertVerifier * cert_verifier,DnsCertProvenanceChecker * dns_cert_checker)299 virtual SSLClientSocket* CreateSSLClientSocket(
300 ClientSocketHandle* transport_socket,
301 const HostPortPair& host_and_port,
302 const SSLConfig& ssl_config,
303 SSLHostInfo* ssl_host_info,
304 CertVerifier* cert_verifier,
305 DnsCertProvenanceChecker* dns_cert_checker) {
306 NOTIMPLEMENTED();
307 delete ssl_host_info;
308 return NULL;
309 }
310
ClearSSLSessionCache()311 virtual void ClearSSLSessionCache() {
312 NOTIMPLEMENTED();
313 }
314
allocation_count() const315 int allocation_count() const { return allocation_count_; }
316
317 // Set the default ClientSocketType.
set_client_socket_type(ClientSocketType type)318 void set_client_socket_type(ClientSocketType type) {
319 client_socket_type_ = type;
320 }
321
322 // Set a list of ClientSocketTypes to be used.
set_client_socket_types(ClientSocketType * type_list,int num_types)323 void set_client_socket_types(ClientSocketType* type_list, int num_types) {
324 DCHECK_GT(num_types, 0);
325 client_socket_types_ = type_list;
326 client_socket_index_ = 0;
327 client_socket_index_max_ = num_types;
328 }
329
set_delay_ms(int delay_ms)330 void set_delay_ms(int delay_ms) { delay_ms_ = delay_ms; }
331
332 private:
333 int allocation_count_;
334 ClientSocketType client_socket_type_;
335 ClientSocketType* client_socket_types_;
336 int client_socket_index_;
337 int client_socket_index_max_;
338 int delay_ms_;
339 };
340
341 class TransportClientSocketPoolTest : public testing::Test {
342 protected:
TransportClientSocketPoolTest()343 TransportClientSocketPoolTest()
344 : connect_backup_jobs_enabled_(
345 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true)),
346 params_(
347 new TransportSocketParams(HostPortPair("www.google.com", 80),
348 kDefaultPriority, GURL(), false, false)),
349 low_params_(
350 new TransportSocketParams(HostPortPair("www.google.com", 80),
351 LOW, GURL(), false, false)),
352 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
353 host_resolver_(new MockHostResolver),
354 pool_(kMaxSockets,
355 kMaxSocketsPerGroup,
356 histograms_.get(),
357 host_resolver_.get(),
358 &client_socket_factory_,
359 NULL) {
360 }
361
~TransportClientSocketPoolTest()362 ~TransportClientSocketPoolTest() {
363 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
364 connect_backup_jobs_enabled_);
365 }
366
StartRequest(const std::string & group_name,RequestPriority priority)367 int StartRequest(const std::string& group_name, RequestPriority priority) {
368 scoped_refptr<TransportSocketParams> params(new TransportSocketParams(
369 HostPortPair("www.google.com", 80), MEDIUM, GURL(), false, false));
370 return test_base_.StartRequestUsingPool(
371 &pool_, group_name, priority, params);
372 }
373
GetOrderOfRequest(size_t index)374 int GetOrderOfRequest(size_t index) {
375 return test_base_.GetOrderOfRequest(index);
376 }
377
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)378 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
379 return test_base_.ReleaseOneConnection(keep_alive);
380 }
381
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)382 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
383 test_base_.ReleaseAllConnections(keep_alive);
384 }
385
requests()386 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
completion_count() const387 size_t completion_count() const { return test_base_.completion_count(); }
388
389 bool connect_backup_jobs_enabled_;
390 scoped_refptr<TransportSocketParams> params_;
391 scoped_refptr<TransportSocketParams> low_params_;
392 scoped_ptr<ClientSocketPoolHistograms> histograms_;
393 scoped_ptr<MockHostResolver> host_resolver_;
394 MockClientSocketFactory client_socket_factory_;
395 TransportClientSocketPool pool_;
396 ClientSocketPoolTest test_base_;
397 };
398
TEST(TransportConnectJobTest,MakeAddrListStartWithIPv4)399 TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
400 IPAddressNumber ip_number;
401 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number));
402 AddressList addrlist_v4_1(ip_number, 80, false);
403 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number));
404 AddressList addrlist_v4_2(ip_number, 80, false);
405 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number));
406 AddressList addrlist_v6_1(ip_number, 80, false);
407 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number));
408 AddressList addrlist_v6_2(ip_number, 80, false);
409
410 AddressList addrlist;
411 const struct addrinfo* ai;
412
413 // Test 1: IPv4 only. Expect no change.
414 addrlist.Copy(addrlist_v4_1.head(), true);
415 addrlist.Append(addrlist_v4_2.head());
416 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
417 ai = addrlist.head();
418 EXPECT_EQ(AF_INET, ai->ai_family);
419 ai = ai->ai_next;
420 EXPECT_EQ(AF_INET, ai->ai_family);
421 EXPECT_TRUE(ai->ai_next == NULL);
422
423 // Test 2: IPv6 only. Expect no change.
424 addrlist.Copy(addrlist_v6_1.head(), true);
425 addrlist.Append(addrlist_v6_2.head());
426 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
427 ai = addrlist.head();
428 EXPECT_EQ(AF_INET6, ai->ai_family);
429 ai = ai->ai_next;
430 EXPECT_EQ(AF_INET6, ai->ai_family);
431 EXPECT_TRUE(ai->ai_next == NULL);
432
433 // Test 3: IPv4 then IPv6. Expect no change.
434 addrlist.Copy(addrlist_v4_1.head(), true);
435 addrlist.Append(addrlist_v4_2.head());
436 addrlist.Append(addrlist_v6_1.head());
437 addrlist.Append(addrlist_v6_2.head());
438 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
439 ai = addrlist.head();
440 EXPECT_EQ(AF_INET, ai->ai_family);
441 ai = ai->ai_next;
442 EXPECT_EQ(AF_INET, ai->ai_family);
443 ai = ai->ai_next;
444 EXPECT_EQ(AF_INET6, ai->ai_family);
445 ai = ai->ai_next;
446 EXPECT_EQ(AF_INET6, ai->ai_family);
447 EXPECT_TRUE(ai->ai_next == NULL);
448
449 // Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end.
450 addrlist.Copy(addrlist_v6_1.head(), true);
451 addrlist.Append(addrlist_v4_1.head());
452 addrlist.Append(addrlist_v6_2.head());
453 addrlist.Append(addrlist_v4_2.head());
454 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
455 ai = addrlist.head();
456 EXPECT_EQ(AF_INET, ai->ai_family);
457 ai = ai->ai_next;
458 EXPECT_EQ(AF_INET6, ai->ai_family);
459 ai = ai->ai_next;
460 EXPECT_EQ(AF_INET, ai->ai_family);
461 ai = ai->ai_next;
462 EXPECT_EQ(AF_INET6, ai->ai_family);
463 EXPECT_TRUE(ai->ai_next == NULL);
464
465 // Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end.
466 addrlist.Copy(addrlist_v6_1.head(), true);
467 addrlist.Append(addrlist_v6_2.head());
468 addrlist.Append(addrlist_v4_1.head());
469 addrlist.Append(addrlist_v4_2.head());
470 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist);
471 ai = addrlist.head();
472 EXPECT_EQ(AF_INET, ai->ai_family);
473 ai = ai->ai_next;
474 EXPECT_EQ(AF_INET, ai->ai_family);
475 ai = ai->ai_next;
476 EXPECT_EQ(AF_INET6, ai->ai_family);
477 ai = ai->ai_next;
478 EXPECT_EQ(AF_INET6, ai->ai_family);
479 EXPECT_TRUE(ai->ai_next == NULL);
480 }
481
TEST_F(TransportClientSocketPoolTest,Basic)482 TEST_F(TransportClientSocketPoolTest, Basic) {
483 TestCompletionCallback callback;
484 ClientSocketHandle handle;
485 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog());
486 EXPECT_EQ(ERR_IO_PENDING, rv);
487 EXPECT_FALSE(handle.is_initialized());
488 EXPECT_FALSE(handle.socket());
489
490 EXPECT_EQ(OK, callback.WaitForResult());
491 EXPECT_TRUE(handle.is_initialized());
492 EXPECT_TRUE(handle.socket());
493
494 handle.Reset();
495 }
496
TEST_F(TransportClientSocketPoolTest,InitHostResolutionFailure)497 TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) {
498 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
499 TestCompletionCallback callback;
500 ClientSocketHandle handle;
501 HostPortPair host_port_pair("unresolvable.host.name", 80);
502 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
503 host_port_pair, kDefaultPriority, GURL(), false, false));
504 EXPECT_EQ(ERR_IO_PENDING,
505 handle.Init("a", dest, kDefaultPriority, &callback, &pool_,
506 BoundNetLog()));
507 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult());
508 }
509
TEST_F(TransportClientSocketPoolTest,InitConnectionFailure)510 TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) {
511 client_socket_factory_.set_client_socket_type(
512 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
513 TestCompletionCallback callback;
514 ClientSocketHandle handle;
515 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
516 &callback, &pool_, BoundNetLog()));
517 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
518
519 // Make the host resolutions complete synchronously this time.
520 host_resolver_->set_synchronous_mode(true);
521 EXPECT_EQ(ERR_CONNECTION_FAILED, handle.Init("a", params_,
522 kDefaultPriority, &callback,
523 &pool_, BoundNetLog()));
524 }
525
TEST_F(TransportClientSocketPoolTest,PendingRequests)526 TEST_F(TransportClientSocketPoolTest, PendingRequests) {
527 // First request finishes asynchronously.
528 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
529 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
530
531 // Make all subsequent host resolutions complete synchronously.
532 host_resolver_->set_synchronous_mode(true);
533
534 // Rest of them finish synchronously, until we reach the per-group limit.
535 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
536 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
537 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
538 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
539 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
540
541 // The rest are pending since we've used all active sockets.
542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
543 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
544 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
545 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
546 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
547 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
548 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
549 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
550 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
551 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
552
553 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
554
555 EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
556
557 // One initial asynchronous request and then 10 pending requests.
558 EXPECT_EQ(11U, completion_count());
559
560 // First part of requests, all with the same priority, finishes in FIFO order.
561 EXPECT_EQ(1, GetOrderOfRequest(1));
562 EXPECT_EQ(2, GetOrderOfRequest(2));
563 EXPECT_EQ(3, GetOrderOfRequest(3));
564 EXPECT_EQ(4, GetOrderOfRequest(4));
565 EXPECT_EQ(5, GetOrderOfRequest(5));
566 EXPECT_EQ(6, GetOrderOfRequest(6));
567
568 // Make sure that rest of the requests complete in the order of priority.
569 EXPECT_EQ(7, GetOrderOfRequest(7));
570 EXPECT_EQ(14, GetOrderOfRequest(8));
571 EXPECT_EQ(15, GetOrderOfRequest(9));
572 EXPECT_EQ(10, GetOrderOfRequest(10));
573 EXPECT_EQ(13, GetOrderOfRequest(11));
574 EXPECT_EQ(8, GetOrderOfRequest(12));
575 EXPECT_EQ(16, GetOrderOfRequest(13));
576 EXPECT_EQ(11, GetOrderOfRequest(14));
577 EXPECT_EQ(12, GetOrderOfRequest(15));
578 EXPECT_EQ(9, GetOrderOfRequest(16));
579
580 // Make sure we test order of all requests made.
581 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(17));
582 }
583
TEST_F(TransportClientSocketPoolTest,PendingRequests_NoKeepAlive)584 TEST_F(TransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
585 // First request finishes asynchronously.
586 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
587 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
588
589 // Make all subsequent host resolutions complete synchronously.
590 host_resolver_->set_synchronous_mode(true);
591
592 // Rest of them finish synchronously, until we reach the per-group limit.
593 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
594 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
595 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
596 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
597 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
598
599 // The rest are pending since we've used all active sockets.
600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
601 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
602 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
603 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
604 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
605
606 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
607
608 // The pending requests should finish successfully.
609 EXPECT_EQ(OK, (*requests())[6]->WaitForResult());
610 EXPECT_EQ(OK, (*requests())[7]->WaitForResult());
611 EXPECT_EQ(OK, (*requests())[8]->WaitForResult());
612 EXPECT_EQ(OK, (*requests())[9]->WaitForResult());
613 EXPECT_EQ(OK, (*requests())[10]->WaitForResult());
614
615 EXPECT_EQ(static_cast<int>(requests()->size()),
616 client_socket_factory_.allocation_count());
617
618 // First asynchronous request, and then last 5 pending requests.
619 EXPECT_EQ(6U, completion_count());
620 }
621
622 // This test will start up a RequestSocket() and then immediately Cancel() it.
623 // The pending host resolution will eventually complete, and destroy the
624 // ClientSocketPool which will crash if the group was not cleared properly.
TEST_F(TransportClientSocketPoolTest,CancelRequestClearGroup)625 TEST_F(TransportClientSocketPoolTest, CancelRequestClearGroup) {
626 TestCompletionCallback callback;
627 ClientSocketHandle handle;
628 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
629 &callback, &pool_, BoundNetLog()));
630 handle.Reset();
631 }
632
TEST_F(TransportClientSocketPoolTest,TwoRequestsCancelOne)633 TEST_F(TransportClientSocketPoolTest, TwoRequestsCancelOne) {
634 ClientSocketHandle handle;
635 TestCompletionCallback callback;
636 ClientSocketHandle handle2;
637 TestCompletionCallback callback2;
638
639 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
640 &callback, &pool_, BoundNetLog()));
641 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
642 &callback2, &pool_, BoundNetLog()));
643
644 handle.Reset();
645
646 EXPECT_EQ(OK, callback2.WaitForResult());
647 handle2.Reset();
648 }
649
TEST_F(TransportClientSocketPoolTest,ConnectCancelConnect)650 TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) {
651 client_socket_factory_.set_client_socket_type(
652 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
653 ClientSocketHandle handle;
654 TestCompletionCallback callback;
655 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
656 &callback, &pool_, BoundNetLog()));
657
658 handle.Reset();
659
660 TestCompletionCallback callback2;
661 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
662 &callback2, &pool_, BoundNetLog()));
663
664 host_resolver_->set_synchronous_mode(true);
665 // At this point, handle has two ConnectingSockets out for it. Due to the
666 // setting the mock resolver into synchronous mode, the host resolution for
667 // both will return in the same loop of the MessageLoop. The client socket
668 // is a pending socket, so the Connect() will asynchronously complete on the
669 // next loop of the MessageLoop. That means that the first
670 // ConnectingSocket will enter OnIOComplete, and then the second one will.
671 // If the first one is not cancelled, it will advance the load state, and
672 // then the second one will crash.
673
674 EXPECT_EQ(OK, callback2.WaitForResult());
675 EXPECT_FALSE(callback.have_result());
676
677 handle.Reset();
678 }
679
TEST_F(TransportClientSocketPoolTest,CancelRequest)680 TEST_F(TransportClientSocketPoolTest, CancelRequest) {
681 // First request finishes asynchronously.
682 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
683 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
684
685 // Make all subsequent host resolutions complete synchronously.
686 host_resolver_->set_synchronous_mode(true);
687
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
690 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
691 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
692 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
693
694 // Reached per-group limit, queue up requests.
695 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
696 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
697 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
698 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
699 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
700 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
701 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
702 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
703 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
704 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
705
706 // Cancel a request.
707 size_t index_to_cancel = kMaxSocketsPerGroup + 2;
708 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
709 (*requests())[index_to_cancel]->handle()->Reset();
710
711 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
712
713 EXPECT_EQ(kMaxSocketsPerGroup,
714 client_socket_factory_.allocation_count());
715 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
716
717 EXPECT_EQ(1, GetOrderOfRequest(1));
718 EXPECT_EQ(2, GetOrderOfRequest(2));
719 EXPECT_EQ(3, GetOrderOfRequest(3));
720 EXPECT_EQ(4, GetOrderOfRequest(4));
721 EXPECT_EQ(5, GetOrderOfRequest(5));
722 EXPECT_EQ(6, GetOrderOfRequest(6));
723 EXPECT_EQ(14, GetOrderOfRequest(7));
724 EXPECT_EQ(7, GetOrderOfRequest(8));
725 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
726 GetOrderOfRequest(9)); // Canceled request.
727 EXPECT_EQ(9, GetOrderOfRequest(10));
728 EXPECT_EQ(10, GetOrderOfRequest(11));
729 EXPECT_EQ(11, GetOrderOfRequest(12));
730 EXPECT_EQ(8, GetOrderOfRequest(13));
731 EXPECT_EQ(12, GetOrderOfRequest(14));
732 EXPECT_EQ(13, GetOrderOfRequest(15));
733 EXPECT_EQ(15, GetOrderOfRequest(16));
734
735 // Make sure we test order of all requests made.
736 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(17));
737 }
738
739 class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
740 public:
RequestSocketCallback(ClientSocketHandle * handle,TransportClientSocketPool * pool)741 RequestSocketCallback(ClientSocketHandle* handle,
742 TransportClientSocketPool* pool)
743 : handle_(handle),
744 pool_(pool),
745 within_callback_(false) {}
746
RunWithParams(const Tuple1<int> & params)747 virtual void RunWithParams(const Tuple1<int>& params) {
748 callback_.RunWithParams(params);
749 ASSERT_EQ(OK, params.a);
750
751 if (!within_callback_) {
752 // Don't allow reuse of the socket. Disconnect it and then release it and
753 // run through the MessageLoop once to get it completely released.
754 handle_->socket()->Disconnect();
755 handle_->Reset();
756 {
757 MessageLoop::ScopedNestableTaskAllower nestable(
758 MessageLoop::current());
759 MessageLoop::current()->RunAllPending();
760 }
761 within_callback_ = true;
762 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
763 HostPortPair("www.google.com", 80), LOWEST, GURL(), false, false));
764 int rv = handle_->Init("a", dest, LOWEST, this, pool_, BoundNetLog());
765 EXPECT_EQ(OK, rv);
766 }
767 }
768
WaitForResult()769 int WaitForResult() {
770 return callback_.WaitForResult();
771 }
772
773 private:
774 ClientSocketHandle* const handle_;
775 TransportClientSocketPool* const pool_;
776 bool within_callback_;
777 TestCompletionCallback callback_;
778 };
779
TEST_F(TransportClientSocketPoolTest,RequestTwice)780 TEST_F(TransportClientSocketPoolTest, RequestTwice) {
781 ClientSocketHandle handle;
782 RequestSocketCallback callback(&handle, &pool_);
783 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
784 HostPortPair("www.google.com", 80), LOWEST, GURL(), false, false));
785 int rv = handle.Init("a", dest, LOWEST, &callback, &pool_,
786 BoundNetLog());
787 ASSERT_EQ(ERR_IO_PENDING, rv);
788
789 // The callback is going to request "www.google.com". We want it to complete
790 // synchronously this time.
791 host_resolver_->set_synchronous_mode(true);
792
793 EXPECT_EQ(OK, callback.WaitForResult());
794
795 handle.Reset();
796 }
797
798 // Make sure that pending requests get serviced after active requests get
799 // cancelled.
TEST_F(TransportClientSocketPoolTest,CancelActiveRequestWithPendingRequests)800 TEST_F(TransportClientSocketPoolTest, CancelActiveRequestWithPendingRequests) {
801 client_socket_factory_.set_client_socket_type(
802 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
803
804 // Queue up all the requests
805 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
806 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
807 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
810 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
812 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
813 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
814
815 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
816 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
817 for (int i = 0; i < kMaxSocketsPerGroup; i++)
818 (*requests())[i]->handle()->Reset();
819
820 // Let's wait for the rest to complete now.
821 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
822 EXPECT_EQ(OK, (*requests())[i]->WaitForResult());
823 (*requests())[i]->handle()->Reset();
824 }
825
826 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
827 }
828
829 // Make sure that pending requests get serviced after active requests fail.
TEST_F(TransportClientSocketPoolTest,FailingActiveRequestWithPendingRequests)830 TEST_F(TransportClientSocketPoolTest, FailingActiveRequestWithPendingRequests) {
831 client_socket_factory_.set_client_socket_type(
832 MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
833
834 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
835 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
836
837 // Queue up all the requests
838 for (int i = 0; i < kNumRequests; i++)
839 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
840
841 for (int i = 0; i < kNumRequests; i++)
842 EXPECT_EQ(ERR_CONNECTION_FAILED, (*requests())[i]->WaitForResult());
843 }
844
TEST_F(TransportClientSocketPoolTest,ResetIdleSocketsOnIPAddressChange)845 TEST_F(TransportClientSocketPoolTest, ResetIdleSocketsOnIPAddressChange) {
846 TestCompletionCallback callback;
847 ClientSocketHandle handle;
848 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog());
849 EXPECT_EQ(ERR_IO_PENDING, rv);
850 EXPECT_FALSE(handle.is_initialized());
851 EXPECT_FALSE(handle.socket());
852
853 EXPECT_EQ(OK, callback.WaitForResult());
854 EXPECT_TRUE(handle.is_initialized());
855 EXPECT_TRUE(handle.socket());
856
857 handle.Reset();
858
859 // Need to run all pending to release the socket back to the pool.
860 MessageLoop::current()->RunAllPending();
861
862 // Now we should have 1 idle socket.
863 EXPECT_EQ(1, pool_.IdleSocketCount());
864
865 // After an IP address change, we should have 0 idle sockets.
866 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
867 MessageLoop::current()->RunAllPending(); // Notification happens async.
868
869 EXPECT_EQ(0, pool_.IdleSocketCount());
870 }
871
TEST_F(TransportClientSocketPoolTest,BackupSocketConnect)872 TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) {
873 // Case 1 tests the first socket stalling, and the backup connecting.
874 MockClientSocketFactory::ClientSocketType case1_types[] = {
875 // The first socket will not connect.
876 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
877 // The second socket will connect more quickly.
878 MockClientSocketFactory::MOCK_CLIENT_SOCKET
879 };
880
881 // Case 2 tests the first socket being slow, so that we start the
882 // second connect, but the second connect stalls, and we still
883 // complete the first.
884 MockClientSocketFactory::ClientSocketType case2_types[] = {
885 // The first socket will connect, although delayed.
886 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
887 // The second socket will not connect.
888 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
889 };
890
891 MockClientSocketFactory::ClientSocketType* cases[2] = {
892 case1_types,
893 case2_types
894 };
895
896 for (size_t index = 0; index < arraysize(cases); ++index) {
897 client_socket_factory_.set_client_socket_types(cases[index], 2);
898
899 EXPECT_EQ(0, pool_.IdleSocketCount());
900
901 TestCompletionCallback callback;
902 ClientSocketHandle handle;
903 int rv = handle.Init("b", low_params_, LOW, &callback, &pool_,
904 BoundNetLog());
905 EXPECT_EQ(ERR_IO_PENDING, rv);
906 EXPECT_FALSE(handle.is_initialized());
907 EXPECT_FALSE(handle.socket());
908
909 // Create the first socket, set the timer.
910 MessageLoop::current()->RunAllPending();
911
912 // Wait for the backup socket timer to fire.
913 base::PlatformThread::Sleep(
914 ClientSocketPool::kMaxConnectRetryIntervalMs + 50);
915
916 // Let the appropriate socket connect.
917 MessageLoop::current()->RunAllPending();
918
919 EXPECT_EQ(OK, callback.WaitForResult());
920 EXPECT_TRUE(handle.is_initialized());
921 EXPECT_TRUE(handle.socket());
922
923 // One socket is stalled, the other is active.
924 EXPECT_EQ(0, pool_.IdleSocketCount());
925 handle.Reset();
926
927 // Close all pending connect jobs and existing sockets.
928 pool_.Flush();
929 }
930 }
931
932 // Test the case where a socket took long enough to start the creation
933 // of the backup socket, but then we cancelled the request after that.
TEST_F(TransportClientSocketPoolTest,BackupSocketCancel)934 TEST_F(TransportClientSocketPoolTest, BackupSocketCancel) {
935 client_socket_factory_.set_client_socket_type(
936 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET);
937
938 enum { CANCEL_BEFORE_WAIT, CANCEL_AFTER_WAIT };
939
940 for (int index = CANCEL_BEFORE_WAIT; index < CANCEL_AFTER_WAIT; ++index) {
941 EXPECT_EQ(0, pool_.IdleSocketCount());
942
943 TestCompletionCallback callback;
944 ClientSocketHandle handle;
945 int rv = handle.Init("c", low_params_, LOW, &callback, &pool_,
946 BoundNetLog());
947 EXPECT_EQ(ERR_IO_PENDING, rv);
948 EXPECT_FALSE(handle.is_initialized());
949 EXPECT_FALSE(handle.socket());
950
951 // Create the first socket, set the timer.
952 MessageLoop::current()->RunAllPending();
953
954 if (index == CANCEL_AFTER_WAIT) {
955 // Wait for the backup socket timer to fire.
956 base::PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs);
957 }
958
959 // Let the appropriate socket connect.
960 MessageLoop::current()->RunAllPending();
961
962 handle.Reset();
963
964 EXPECT_FALSE(callback.have_result());
965 EXPECT_FALSE(handle.is_initialized());
966 EXPECT_FALSE(handle.socket());
967
968 // One socket is stalled, the other is active.
969 EXPECT_EQ(0, pool_.IdleSocketCount());
970 }
971 }
972
973 // Test the case where a socket took long enough to start the creation
974 // of the backup socket and never completes, and then the backup
975 // connection fails.
TEST_F(TransportClientSocketPoolTest,BackupSocketFailAfterStall)976 TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterStall) {
977 MockClientSocketFactory::ClientSocketType case_types[] = {
978 // The first socket will not connect.
979 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
980 // The second socket will fail immediately.
981 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
982 };
983
984 client_socket_factory_.set_client_socket_types(case_types, 2);
985
986 EXPECT_EQ(0, pool_.IdleSocketCount());
987
988 TestCompletionCallback callback;
989 ClientSocketHandle handle;
990 int rv = handle.Init("b", low_params_, LOW, &callback, &pool_, BoundNetLog());
991 EXPECT_EQ(ERR_IO_PENDING, rv);
992 EXPECT_FALSE(handle.is_initialized());
993 EXPECT_FALSE(handle.socket());
994
995 // Create the first socket, set the timer.
996 MessageLoop::current()->RunAllPending();
997
998 // Wait for the backup socket timer to fire.
999 base::PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs);
1000
1001 // Let the second connect be synchronous. Otherwise, the emulated
1002 // host resolution takes an extra trip through the message loop.
1003 host_resolver_->set_synchronous_mode(true);
1004
1005 // Let the appropriate socket connect.
1006 MessageLoop::current()->RunAllPending();
1007
1008 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1009 EXPECT_FALSE(handle.is_initialized());
1010 EXPECT_FALSE(handle.socket());
1011 EXPECT_EQ(0, pool_.IdleSocketCount());
1012 handle.Reset();
1013
1014 // Reset for the next case.
1015 host_resolver_->set_synchronous_mode(false);
1016 }
1017
1018 // Test the case where a socket took long enough to start the creation
1019 // of the backup socket and eventually completes, but the backup socket
1020 // fails.
TEST_F(TransportClientSocketPoolTest,BackupSocketFailAfterDelay)1021 TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) {
1022 MockClientSocketFactory::ClientSocketType case_types[] = {
1023 // The first socket will connect, although delayed.
1024 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
1025 // The second socket will not connect.
1026 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
1027 };
1028
1029 client_socket_factory_.set_client_socket_types(case_types, 2);
1030
1031 EXPECT_EQ(0, pool_.IdleSocketCount());
1032
1033 TestCompletionCallback callback;
1034 ClientSocketHandle handle;
1035 int rv = handle.Init("b", low_params_, LOW, &callback, &pool_, BoundNetLog());
1036 EXPECT_EQ(ERR_IO_PENDING, rv);
1037 EXPECT_FALSE(handle.is_initialized());
1038 EXPECT_FALSE(handle.socket());
1039
1040 // Create the first socket, set the timer.
1041 MessageLoop::current()->RunAllPending();
1042
1043 // Wait for the backup socket timer to fire.
1044 base::PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs);
1045
1046 // Let the second connect be synchronous. Otherwise, the emulated
1047 // host resolution takes an extra trip through the message loop.
1048 host_resolver_->set_synchronous_mode(true);
1049
1050 // Let the appropriate socket connect.
1051 MessageLoop::current()->RunAllPending();
1052
1053 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1054 EXPECT_FALSE(handle.is_initialized());
1055 EXPECT_FALSE(handle.socket());
1056 handle.Reset();
1057
1058 // Reset for the next case.
1059 host_resolver_->set_synchronous_mode(false);
1060 }
1061
1062 // Test the case of the IPv6 address stalling, and falling back to the IPv4
1063 // socket which finishes first.
TEST_F(TransportClientSocketPoolTest,IPv6FallbackSocketIPv4FinishesFirst)1064 TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) {
1065 // Create a pool without backup jobs.
1066 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
1067 TransportClientSocketPool pool(kMaxSockets,
1068 kMaxSocketsPerGroup,
1069 histograms_.get(),
1070 host_resolver_.get(),
1071 &client_socket_factory_,
1072 NULL);
1073
1074 MockClientSocketFactory::ClientSocketType case_types[] = {
1075 // This is the IPv6 socket.
1076 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
1077 // This is the IPv4 socket.
1078 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
1079 };
1080
1081 client_socket_factory_.set_client_socket_types(case_types, 2);
1082
1083 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
1084 host_resolver_->rules()->AddIPLiteralRule(
1085 "*", "2:abcd::3:4:ff,2.2.2.2", "");
1086
1087 TestCompletionCallback callback;
1088 ClientSocketHandle handle;
1089 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog());
1090 EXPECT_EQ(ERR_IO_PENDING, rv);
1091 EXPECT_FALSE(handle.is_initialized());
1092 EXPECT_FALSE(handle.socket());
1093
1094 EXPECT_EQ(OK, callback.WaitForResult());
1095 EXPECT_TRUE(handle.is_initialized());
1096 EXPECT_TRUE(handle.socket());
1097 IPEndPoint endpoint;
1098 handle.socket()->GetLocalAddress(&endpoint);
1099 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
1100 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1101 }
1102
1103 // Test the case of the IPv6 address being slow, thus falling back to trying to
1104 // connect to the IPv4 address, but having the connect to the IPv6 address
1105 // finish first.
TEST_F(TransportClientSocketPoolTest,IPv6FallbackSocketIPv6FinishesFirst)1106 TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) {
1107 // Create a pool without backup jobs.
1108 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
1109 TransportClientSocketPool pool(kMaxSockets,
1110 kMaxSocketsPerGroup,
1111 histograms_.get(),
1112 host_resolver_.get(),
1113 &client_socket_factory_,
1114 NULL);
1115
1116 MockClientSocketFactory::ClientSocketType case_types[] = {
1117 // This is the IPv6 socket.
1118 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
1119 // This is the IPv4 socket.
1120 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
1121 };
1122
1123 client_socket_factory_.set_client_socket_types(case_types, 2);
1124 client_socket_factory_.set_delay_ms(
1125 TransportConnectJob::kIPv6FallbackTimerInMs + 50);
1126
1127 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
1128 host_resolver_->rules()->AddIPLiteralRule(
1129 "*", "2:abcd::3:4:ff,2.2.2.2", "");
1130
1131 TestCompletionCallback callback;
1132 ClientSocketHandle handle;
1133 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog());
1134 EXPECT_EQ(ERR_IO_PENDING, rv);
1135 EXPECT_FALSE(handle.is_initialized());
1136 EXPECT_FALSE(handle.socket());
1137
1138 EXPECT_EQ(OK, callback.WaitForResult());
1139 EXPECT_TRUE(handle.is_initialized());
1140 EXPECT_TRUE(handle.socket());
1141 IPEndPoint endpoint;
1142 handle.socket()->GetLocalAddress(&endpoint);
1143 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
1144 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1145 }
1146
TEST_F(TransportClientSocketPoolTest,IPv6NoIPv4AddressesToFallbackTo)1147 TEST_F(TransportClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) {
1148 // Create a pool without backup jobs.
1149 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
1150 TransportClientSocketPool pool(kMaxSockets,
1151 kMaxSocketsPerGroup,
1152 histograms_.get(),
1153 host_resolver_.get(),
1154 &client_socket_factory_,
1155 NULL);
1156
1157 client_socket_factory_.set_client_socket_type(
1158 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
1159
1160 // Resolve an AddressList with only IPv6 addresses.
1161 host_resolver_->rules()->AddIPLiteralRule(
1162 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", "");
1163
1164 TestCompletionCallback callback;
1165 ClientSocketHandle handle;
1166 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog());
1167 EXPECT_EQ(ERR_IO_PENDING, rv);
1168 EXPECT_FALSE(handle.is_initialized());
1169 EXPECT_FALSE(handle.socket());
1170
1171 EXPECT_EQ(OK, callback.WaitForResult());
1172 EXPECT_TRUE(handle.is_initialized());
1173 EXPECT_TRUE(handle.socket());
1174 IPEndPoint endpoint;
1175 handle.socket()->GetLocalAddress(&endpoint);
1176 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
1177 EXPECT_EQ(1, client_socket_factory_.allocation_count());
1178 }
1179
TEST_F(TransportClientSocketPoolTest,IPv4HasNoFallback)1180 TEST_F(TransportClientSocketPoolTest, IPv4HasNoFallback) {
1181 // Create a pool without backup jobs.
1182 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
1183 TransportClientSocketPool pool(kMaxSockets,
1184 kMaxSocketsPerGroup,
1185 histograms_.get(),
1186 host_resolver_.get(),
1187 &client_socket_factory_,
1188 NULL);
1189
1190 client_socket_factory_.set_client_socket_type(
1191 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
1192
1193 // Resolve an AddressList with only IPv4 addresses.
1194 host_resolver_->rules()->AddIPLiteralRule(
1195 "*", "1.1.1.1", "");
1196
1197 TestCompletionCallback callback;
1198 ClientSocketHandle handle;
1199 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog());
1200 EXPECT_EQ(ERR_IO_PENDING, rv);
1201 EXPECT_FALSE(handle.is_initialized());
1202 EXPECT_FALSE(handle.socket());
1203
1204 EXPECT_EQ(OK, callback.WaitForResult());
1205 EXPECT_TRUE(handle.is_initialized());
1206 EXPECT_TRUE(handle.socket());
1207 IPEndPoint endpoint;
1208 handle.socket()->GetLocalAddress(&endpoint);
1209 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
1210 EXPECT_EQ(1, client_socket_factory_.allocation_count());
1211 }
1212
1213 } // namespace
1214
1215 } // namespace net
1216