OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/tcp_client_socket_pool.h" | 5 #include "net/socket/tcp_client_socket_pool.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/logging.h" |
9 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
10 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
| 12 #include "net/base/ip_endpoint.h" |
11 #include "net/base/mock_host_resolver.h" | 13 #include "net/base/mock_host_resolver.h" |
12 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/base/net_util.h" |
| 16 #include "net/base/sys_addrinfo.h" |
13 #include "net/base/test_completion_callback.h" | 17 #include "net/base/test_completion_callback.h" |
14 #include "net/socket/client_socket.h" | 18 #include "net/socket/client_socket.h" |
15 #include "net/socket/client_socket_factory.h" | 19 #include "net/socket/client_socket_factory.h" |
16 #include "net/socket/client_socket_handle.h" | 20 #include "net/socket/client_socket_handle.h" |
17 #include "net/socket/client_socket_pool_histograms.h" | 21 #include "net/socket/client_socket_pool_histograms.h" |
18 #include "net/socket/socket_test_util.h" | 22 #include "net/socket/socket_test_util.h" |
19 #include "net/socket/ssl_host_info.h" | 23 #include "net/socket/ssl_host_info.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
21 | 25 |
22 namespace net { | 26 namespace net { |
23 | 27 |
24 namespace { | 28 namespace { |
25 | 29 |
26 const int kMaxSockets = 32; | 30 const int kMaxSockets = 32; |
27 const int kMaxSocketsPerGroup = 6; | 31 const int kMaxSocketsPerGroup = 6; |
28 const net::RequestPriority kDefaultPriority = LOW; | 32 const net::RequestPriority kDefaultPriority = LOW; |
29 | 33 |
| 34 void SetIPv4Address(IPEndPoint* address) { |
| 35 IPAddressNumber number; |
| 36 CHECK(ParseIPLiteralToNumber("1.1.1.1", &number)); |
| 37 *address = IPEndPoint(number, 80); |
| 38 } |
| 39 |
| 40 void SetIPv6Address(IPEndPoint* address) { |
| 41 IPAddressNumber number; |
| 42 CHECK(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number)); |
| 43 *address = IPEndPoint(number, 80); |
| 44 } |
| 45 |
30 class MockClientSocket : public ClientSocket { | 46 class MockClientSocket : public ClientSocket { |
31 public: | 47 public: |
32 MockClientSocket() : connected_(false) {} | 48 MockClientSocket(const AddressList& addrlist) |
| 49 : connected_(false), |
| 50 addrlist_(addrlist) {} |
33 | 51 |
34 // ClientSocket methods: | 52 // ClientSocket methods: |
35 virtual int Connect(CompletionCallback* callback) { | 53 virtual int Connect(CompletionCallback* callback) { |
36 connected_ = true; | 54 connected_ = true; |
37 return OK; | 55 return OK; |
38 } | 56 } |
39 virtual void Disconnect() { | 57 virtual void Disconnect() { |
40 connected_ = false; | 58 connected_ = false; |
41 } | 59 } |
42 virtual bool IsConnected() const { | 60 virtual bool IsConnected() const { |
(...skipping 21 matching lines...) Expand all Loading... |
64 } | 82 } |
65 virtual int Write(IOBuffer* buf, int buf_len, | 83 virtual int Write(IOBuffer* buf, int buf_len, |
66 CompletionCallback* callback) { | 84 CompletionCallback* callback) { |
67 return ERR_FAILED; | 85 return ERR_FAILED; |
68 } | 86 } |
69 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 87 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
70 virtual bool SetSendBufferSize(int32 size) { return true; } | 88 virtual bool SetSendBufferSize(int32 size) { return true; } |
71 | 89 |
72 private: | 90 private: |
73 bool connected_; | 91 bool connected_; |
| 92 const AddressList addrlist_; |
74 BoundNetLog net_log_; | 93 BoundNetLog net_log_; |
75 }; | 94 }; |
76 | 95 |
77 class MockFailingClientSocket : public ClientSocket { | 96 class MockFailingClientSocket : public ClientSocket { |
78 public: | 97 public: |
79 MockFailingClientSocket() {} | 98 MockFailingClientSocket(const AddressList& addrlist) : addrlist_(addrlist) {} |
80 | 99 |
81 // ClientSocket methods: | 100 // ClientSocket methods: |
82 virtual int Connect(CompletionCallback* callback) { | 101 virtual int Connect(CompletionCallback* callback) { |
83 return ERR_CONNECTION_FAILED; | 102 return ERR_CONNECTION_FAILED; |
84 } | 103 } |
85 | 104 |
86 virtual void Disconnect() {} | 105 virtual void Disconnect() {} |
87 | 106 |
88 virtual bool IsConnected() const { | 107 virtual bool IsConnected() const { |
89 return false; | 108 return false; |
(...skipping 20 matching lines...) Expand all Loading... |
110 } | 129 } |
111 | 130 |
112 virtual int Write(IOBuffer* buf, int buf_len, | 131 virtual int Write(IOBuffer* buf, int buf_len, |
113 CompletionCallback* callback) { | 132 CompletionCallback* callback) { |
114 return ERR_FAILED; | 133 return ERR_FAILED; |
115 } | 134 } |
116 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 135 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
117 virtual bool SetSendBufferSize(int32 size) { return true; } | 136 virtual bool SetSendBufferSize(int32 size) { return true; } |
118 | 137 |
119 private: | 138 private: |
| 139 const AddressList addrlist_; |
120 BoundNetLog net_log_; | 140 BoundNetLog net_log_; |
121 }; | 141 }; |
122 | 142 |
123 class MockPendingClientSocket : public ClientSocket { | 143 class MockPendingClientSocket : public ClientSocket { |
124 public: | 144 public: |
125 // |should_connect| indicates whether the socket should successfully complete | 145 // |should_connect| indicates whether the socket should successfully complete |
126 // or fail. | 146 // or fail. |
127 // |should_stall| indicates that this socket should never connect. | 147 // |should_stall| indicates that this socket should never connect. |
128 // |delay_ms| is the delay, in milliseconds, before simulating a connect. | 148 // |delay_ms| is the delay, in milliseconds, before simulating a connect. |
129 MockPendingClientSocket(bool should_connect, bool should_stall, int delay_ms) | 149 MockPendingClientSocket( |
| 150 const AddressList& addrlist, |
| 151 bool should_connect, |
| 152 bool should_stall, |
| 153 int delay_ms) |
130 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 154 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
131 should_connect_(should_connect), | 155 should_connect_(should_connect), |
132 should_stall_(should_stall), | 156 should_stall_(should_stall), |
133 delay_ms_(delay_ms), | 157 delay_ms_(delay_ms), |
134 is_connected_(false) {} | 158 is_connected_(false), |
| 159 addrlist_(addrlist) {} |
135 | 160 |
136 // ClientSocket methods: | 161 // ClientSocket methods: |
137 virtual int Connect(CompletionCallback* callback) { | 162 virtual int Connect(CompletionCallback* callback) { |
138 MessageLoop::current()->PostDelayedTask( | 163 MessageLoop::current()->PostDelayedTask( |
139 FROM_HERE, | 164 FROM_HERE, |
140 method_factory_.NewRunnableMethod( | 165 method_factory_.NewRunnableMethod( |
141 &MockPendingClientSocket::DoCallback, callback), delay_ms_); | 166 &MockPendingClientSocket::DoCallback, callback), delay_ms_); |
142 return ERR_IO_PENDING; | 167 return ERR_IO_PENDING; |
143 } | 168 } |
144 | 169 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 is_connected_ = false; | 212 is_connected_ = false; |
188 callback->Run(ERR_CONNECTION_FAILED); | 213 callback->Run(ERR_CONNECTION_FAILED); |
189 } | 214 } |
190 } | 215 } |
191 | 216 |
192 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; | 217 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; |
193 bool should_connect_; | 218 bool should_connect_; |
194 bool should_stall_; | 219 bool should_stall_; |
195 int delay_ms_; | 220 int delay_ms_; |
196 bool is_connected_; | 221 bool is_connected_; |
| 222 const AddressList addrlist_; |
197 BoundNetLog net_log_; | 223 BoundNetLog net_log_; |
198 }; | 224 }; |
199 | 225 |
200 class MockClientSocketFactory : public ClientSocketFactory { | 226 class MockClientSocketFactory : public ClientSocketFactory { |
201 public: | 227 public: |
202 enum ClientSocketType { | 228 enum ClientSocketType { |
203 MOCK_CLIENT_SOCKET, | 229 MOCK_CLIENT_SOCKET, |
204 MOCK_FAILING_CLIENT_SOCKET, | 230 MOCK_FAILING_CLIENT_SOCKET, |
205 MOCK_PENDING_CLIENT_SOCKET, | 231 MOCK_PENDING_CLIENT_SOCKET, |
206 MOCK_PENDING_FAILING_CLIENT_SOCKET, | 232 MOCK_PENDING_FAILING_CLIENT_SOCKET, |
207 // A delayed socket will pause before connecting through the message loop. | 233 // A delayed socket will pause before connecting through the message loop. |
208 MOCK_DELAYED_CLIENT_SOCKET, | 234 MOCK_DELAYED_CLIENT_SOCKET, |
209 // A stalled socket that never connects at all. | 235 // A stalled socket that never connects at all. |
210 MOCK_STALLED_CLIENT_SOCKET, | 236 MOCK_STALLED_CLIENT_SOCKET, |
211 }; | 237 }; |
212 | 238 |
213 MockClientSocketFactory() | 239 MockClientSocketFactory() |
214 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), | 240 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), |
215 client_socket_types_(NULL), client_socket_index_(0), | 241 client_socket_types_(NULL), client_socket_index_(0), |
216 client_socket_index_max_(0) {} | 242 client_socket_index_max_(0), |
| 243 delay_ms_(ClientSocketPool::kMaxConnectRetryIntervalMs) {} |
217 | 244 |
218 virtual ClientSocket* CreateTCPClientSocket( | 245 virtual ClientSocket* CreateTCPClientSocket( |
219 const AddressList& addresses, | 246 const AddressList& addresses, |
220 NetLog* /* net_log */, | 247 NetLog* /* net_log */, |
221 const NetLog::Source& /* source */) { | 248 const NetLog::Source& /* source */) { |
222 allocation_count_++; | 249 allocation_count_++; |
223 | 250 |
224 ClientSocketType type = client_socket_type_; | 251 ClientSocketType type = client_socket_type_; |
225 if (client_socket_types_ && | 252 if (client_socket_types_ && |
226 client_socket_index_ < client_socket_index_max_) { | 253 client_socket_index_ < client_socket_index_max_) { |
227 type = client_socket_types_[client_socket_index_++]; | 254 type = client_socket_types_[client_socket_index_++]; |
228 } | 255 } |
229 | 256 |
230 switch (type) { | 257 switch (type) { |
231 case MOCK_CLIENT_SOCKET: | 258 case MOCK_CLIENT_SOCKET: |
232 return new MockClientSocket(); | 259 return new MockClientSocket(addresses); |
233 case MOCK_FAILING_CLIENT_SOCKET: | 260 case MOCK_FAILING_CLIENT_SOCKET: |
234 return new MockFailingClientSocket(); | 261 return new MockFailingClientSocket(addresses); |
235 case MOCK_PENDING_CLIENT_SOCKET: | 262 case MOCK_PENDING_CLIENT_SOCKET: |
236 return new MockPendingClientSocket(true, false, 0); | 263 return new MockPendingClientSocket(addresses, true, false, 0); |
237 case MOCK_PENDING_FAILING_CLIENT_SOCKET: | 264 case MOCK_PENDING_FAILING_CLIENT_SOCKET: |
238 return new MockPendingClientSocket(false, false, 0); | 265 return new MockPendingClientSocket(addresses, false, false, 0); |
239 case MOCK_DELAYED_CLIENT_SOCKET: | 266 case MOCK_DELAYED_CLIENT_SOCKET: |
240 return new MockPendingClientSocket(true, false, | 267 return new MockPendingClientSocket(addresses, true, false, delay_ms_); |
241 ClientSocketPool::kMaxConnectRetryIntervalMs); | |
242 case MOCK_STALLED_CLIENT_SOCKET: | 268 case MOCK_STALLED_CLIENT_SOCKET: |
243 return new MockPendingClientSocket(true, true, 0); | 269 return new MockPendingClientSocket(addresses, true, true, 0); |
244 default: | 270 default: |
245 NOTREACHED(); | 271 NOTREACHED(); |
246 return new MockClientSocket(); | 272 return new MockClientSocket(addresses); |
247 } | 273 } |
248 } | 274 } |
249 | 275 |
250 virtual SSLClientSocket* CreateSSLClientSocket( | 276 virtual SSLClientSocket* CreateSSLClientSocket( |
251 ClientSocketHandle* transport_socket, | 277 ClientSocketHandle* transport_socket, |
252 const HostPortPair& host_and_port, | 278 const HostPortPair& host_and_port, |
253 const SSLConfig& ssl_config, | 279 const SSLConfig& ssl_config, |
254 SSLHostInfo* ssl_host_info, | 280 SSLHostInfo* ssl_host_info, |
255 CertVerifier* cert_verifier, | 281 CertVerifier* cert_verifier, |
256 DnsCertProvenanceChecker* dns_cert_checker) { | 282 DnsCertProvenanceChecker* dns_cert_checker) { |
(...skipping 14 matching lines...) Expand all Loading... |
271 } | 297 } |
272 | 298 |
273 // Set a list of ClientSocketTypes to be used. | 299 // Set a list of ClientSocketTypes to be used. |
274 void set_client_socket_types(ClientSocketType* type_list, int num_types) { | 300 void set_client_socket_types(ClientSocketType* type_list, int num_types) { |
275 DCHECK_GT(num_types, 0); | 301 DCHECK_GT(num_types, 0); |
276 client_socket_types_ = type_list; | 302 client_socket_types_ = type_list; |
277 client_socket_index_ = 0; | 303 client_socket_index_ = 0; |
278 client_socket_index_max_ = num_types; | 304 client_socket_index_max_ = num_types; |
279 } | 305 } |
280 | 306 |
| 307 void set_delay_ms(int delay_ms) { delay_ms_ = delay_ms; } |
| 308 |
281 private: | 309 private: |
282 int allocation_count_; | 310 int allocation_count_; |
283 ClientSocketType client_socket_type_; | 311 ClientSocketType client_socket_type_; |
284 ClientSocketType* client_socket_types_; | 312 ClientSocketType* client_socket_types_; |
285 int client_socket_index_; | 313 int client_socket_index_; |
286 int client_socket_index_max_; | 314 int client_socket_index_max_; |
| 315 int delay_ms_; |
287 }; | 316 }; |
288 | 317 |
289 class TCPClientSocketPoolTest : public testing::Test { | 318 class TCPClientSocketPoolTest : public testing::Test { |
290 protected: | 319 protected: |
291 TCPClientSocketPoolTest() | 320 TCPClientSocketPoolTest() |
292 : params_(new TCPSocketParams(HostPortPair("www.google.com", 80), | 321 : params_(new TCPSocketParams(HostPortPair("www.google.com", 80), |
293 kDefaultPriority, GURL(), false)), | 322 kDefaultPriority, GURL(), false)), |
294 low_params_(new TCPSocketParams(HostPortPair("www.google.com", 80), | 323 low_params_(new TCPSocketParams(HostPortPair("www.google.com", 80), |
295 LOW, GURL(), false)), | 324 LOW, GURL(), false)), |
296 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), | 325 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), |
(...skipping 30 matching lines...) Expand all Loading... |
327 | 356 |
328 scoped_refptr<TCPSocketParams> params_; | 357 scoped_refptr<TCPSocketParams> params_; |
329 scoped_refptr<TCPSocketParams> low_params_; | 358 scoped_refptr<TCPSocketParams> low_params_; |
330 scoped_ptr<ClientSocketPoolHistograms> histograms_; | 359 scoped_ptr<ClientSocketPoolHistograms> histograms_; |
331 scoped_ptr<MockHostResolver> host_resolver_; | 360 scoped_ptr<MockHostResolver> host_resolver_; |
332 MockClientSocketFactory client_socket_factory_; | 361 MockClientSocketFactory client_socket_factory_; |
333 TCPClientSocketPool pool_; | 362 TCPClientSocketPool pool_; |
334 ClientSocketPoolTest test_base_; | 363 ClientSocketPoolTest test_base_; |
335 }; | 364 }; |
336 | 365 |
| 366 TEST(TCPConnectJobTest, MakeAddrListStartWithIPv4) { |
| 367 IPAddressNumber ip_number; |
| 368 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number)); |
| 369 AddressList addrlist_v4_1(ip_number, 80, false); |
| 370 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number)); |
| 371 AddressList addrlist_v4_2(ip_number, 80, false); |
| 372 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number)); |
| 373 AddressList addrlist_v6_1(ip_number, 80, false); |
| 374 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number)); |
| 375 AddressList addrlist_v6_2(ip_number, 80, false); |
| 376 |
| 377 AddressList addrlist; |
| 378 const struct addrinfo* ai; |
| 379 |
| 380 // Test 1: IPv4 only. Expect no change. |
| 381 addrlist.Copy(addrlist_v4_1.head(), true); |
| 382 addrlist.Append(addrlist_v4_2.head()); |
| 383 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 384 ai = addrlist.head(); |
| 385 EXPECT_EQ(AF_INET, ai->ai_family); |
| 386 ai = ai->ai_next; |
| 387 EXPECT_EQ(AF_INET, ai->ai_family); |
| 388 EXPECT_TRUE(ai->ai_next == NULL); |
| 389 |
| 390 // Test 2: IPv6 only. Expect no change. |
| 391 addrlist.Copy(addrlist_v6_1.head(), true); |
| 392 addrlist.Append(addrlist_v6_2.head()); |
| 393 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 394 ai = addrlist.head(); |
| 395 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 396 ai = ai->ai_next; |
| 397 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 398 EXPECT_TRUE(ai->ai_next == NULL); |
| 399 |
| 400 // Test 3: IPv4 then IPv6. Expect no change. |
| 401 addrlist.Copy(addrlist_v4_1.head(), true); |
| 402 addrlist.Append(addrlist_v4_2.head()); |
| 403 addrlist.Append(addrlist_v6_1.head()); |
| 404 addrlist.Append(addrlist_v6_2.head()); |
| 405 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 406 ai = addrlist.head(); |
| 407 EXPECT_EQ(AF_INET, ai->ai_family); |
| 408 ai = ai->ai_next; |
| 409 EXPECT_EQ(AF_INET, ai->ai_family); |
| 410 ai = ai->ai_next; |
| 411 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 412 ai = ai->ai_next; |
| 413 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 414 EXPECT_TRUE(ai->ai_next == NULL); |
| 415 |
| 416 // Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end. |
| 417 addrlist.Copy(addrlist_v6_1.head(), true); |
| 418 addrlist.Append(addrlist_v4_1.head()); |
| 419 addrlist.Append(addrlist_v6_2.head()); |
| 420 addrlist.Append(addrlist_v4_2.head()); |
| 421 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 422 ai = addrlist.head(); |
| 423 EXPECT_EQ(AF_INET, ai->ai_family); |
| 424 ai = ai->ai_next; |
| 425 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 426 ai = ai->ai_next; |
| 427 EXPECT_EQ(AF_INET, ai->ai_family); |
| 428 ai = ai->ai_next; |
| 429 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 430 EXPECT_TRUE(ai->ai_next == NULL); |
| 431 |
| 432 // Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end. |
| 433 addrlist.Copy(addrlist_v6_1.head(), true); |
| 434 addrlist.Append(addrlist_v6_2.head()); |
| 435 addrlist.Append(addrlist_v4_1.head()); |
| 436 addrlist.Append(addrlist_v4_2.head()); |
| 437 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 438 ai = addrlist.head(); |
| 439 EXPECT_EQ(AF_INET, ai->ai_family); |
| 440 ai = ai->ai_next; |
| 441 EXPECT_EQ(AF_INET, ai->ai_family); |
| 442 ai = ai->ai_next; |
| 443 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 444 ai = ai->ai_next; |
| 445 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 446 EXPECT_TRUE(ai->ai_next == NULL); |
| 447 } |
| 448 |
337 TEST_F(TCPClientSocketPoolTest, Basic) { | 449 TEST_F(TCPClientSocketPoolTest, Basic) { |
338 TestCompletionCallback callback; | 450 TestCompletionCallback callback; |
339 ClientSocketHandle handle; | 451 ClientSocketHandle handle; |
340 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); | 452 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); |
341 EXPECT_EQ(ERR_IO_PENDING, rv); | 453 EXPECT_EQ(ERR_IO_PENDING, rv); |
342 EXPECT_FALSE(handle.is_initialized()); | 454 EXPECT_FALSE(handle.is_initialized()); |
343 EXPECT_FALSE(handle.socket()); | 455 EXPECT_FALSE(handle.socket()); |
344 | 456 |
345 EXPECT_EQ(OK, callback.WaitForResult()); | 457 EXPECT_EQ(OK, callback.WaitForResult()); |
346 EXPECT_TRUE(handle.is_initialized()); | 458 EXPECT_TRUE(handle.is_initialized()); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 BoundNetLog()); | 869 BoundNetLog()); |
758 EXPECT_EQ(ERR_IO_PENDING, rv); | 870 EXPECT_EQ(ERR_IO_PENDING, rv); |
759 EXPECT_FALSE(handle.is_initialized()); | 871 EXPECT_FALSE(handle.is_initialized()); |
760 EXPECT_FALSE(handle.socket()); | 872 EXPECT_FALSE(handle.socket()); |
761 | 873 |
762 // Create the first socket, set the timer. | 874 // Create the first socket, set the timer. |
763 MessageLoop::current()->RunAllPending(); | 875 MessageLoop::current()->RunAllPending(); |
764 | 876 |
765 // Wait for the backup socket timer to fire. | 877 // Wait for the backup socket timer to fire. |
766 base::PlatformThread::Sleep( | 878 base::PlatformThread::Sleep( |
767 ClientSocketPool::kMaxConnectRetryIntervalMs * 2); | 879 ClientSocketPool::kMaxConnectRetryIntervalMs + 50); |
768 | 880 |
769 // Let the appropriate socket connect. | 881 // Let the appropriate socket connect. |
770 MessageLoop::current()->RunAllPending(); | 882 MessageLoop::current()->RunAllPending(); |
771 | 883 |
772 EXPECT_EQ(OK, callback.WaitForResult()); | 884 EXPECT_EQ(OK, callback.WaitForResult()); |
773 EXPECT_TRUE(handle.is_initialized()); | 885 EXPECT_TRUE(handle.is_initialized()); |
774 EXPECT_TRUE(handle.socket()); | 886 EXPECT_TRUE(handle.socket()); |
775 | 887 |
776 // One socket is stalled, the other is active. | 888 // One socket is stalled, the other is active. |
777 EXPECT_EQ(0, pool_.IdleSocketCount()); | 889 EXPECT_EQ(0, pool_.IdleSocketCount()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 | 1017 |
906 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); | 1018 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); |
907 EXPECT_FALSE(handle.is_initialized()); | 1019 EXPECT_FALSE(handle.is_initialized()); |
908 EXPECT_FALSE(handle.socket()); | 1020 EXPECT_FALSE(handle.socket()); |
909 handle.Reset(); | 1021 handle.Reset(); |
910 | 1022 |
911 // Reset for the next case. | 1023 // Reset for the next case. |
912 host_resolver_->set_synchronous_mode(false); | 1024 host_resolver_->set_synchronous_mode(false); |
913 } | 1025 } |
914 | 1026 |
| 1027 // Test the case of the IPv6 address stalling, and falling back to the IPv4 |
| 1028 // socket which finishes first. |
| 1029 TEST_F(TCPClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) { |
| 1030 TCPClientSocketPool pool(1, |
| 1031 1, |
| 1032 histograms_.get(), |
| 1033 host_resolver_.get(), |
| 1034 &client_socket_factory_, |
| 1035 NULL); |
| 1036 |
| 1037 MockClientSocketFactory::ClientSocketType case_types[] = { |
| 1038 // This is the IPv6 socket. |
| 1039 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, |
| 1040 // This is the IPv4 socket. |
| 1041 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET |
| 1042 }; |
| 1043 |
| 1044 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1045 |
| 1046 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1047 host_resolver_->rules()->AddIPLiteralRule( |
| 1048 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1049 |
| 1050 TestCompletionCallback callback; |
| 1051 ClientSocketHandle handle; |
| 1052 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1053 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1054 EXPECT_FALSE(handle.is_initialized()); |
| 1055 EXPECT_FALSE(handle.socket()); |
| 1056 |
| 1057 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1058 EXPECT_TRUE(handle.is_initialized()); |
| 1059 EXPECT_TRUE(handle.socket()); |
| 1060 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1061 } |
| 1062 |
| 1063 // Test the case of the IPv6 address being slow, thus falling back to trying to |
| 1064 // connect to the IPv4 address, but having the connect to the IPv6 address |
| 1065 // finish first. |
| 1066 TEST_F(TCPClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) { |
| 1067 TCPClientSocketPool pool(1, |
| 1068 1, |
| 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_DELAYED_CLIENT_SOCKET, |
| 1077 // This is the IPv4 socket. |
| 1078 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET |
| 1079 }; |
| 1080 |
| 1081 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1082 client_socket_factory_.set_delay_ms( |
| 1083 TCPConnectJob::kIPv6FallbackTimerInMs + 50); |
| 1084 |
| 1085 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1086 host_resolver_->rules()->AddIPLiteralRule( |
| 1087 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1088 |
| 1089 TestCompletionCallback callback; |
| 1090 ClientSocketHandle handle; |
| 1091 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1092 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1093 EXPECT_FALSE(handle.is_initialized()); |
| 1094 EXPECT_FALSE(handle.socket()); |
| 1095 |
| 1096 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1097 EXPECT_TRUE(handle.is_initialized()); |
| 1098 EXPECT_TRUE(handle.socket()); |
| 1099 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1100 } |
| 1101 |
| 1102 TEST_F(TCPClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) { |
| 1103 TCPClientSocketPool pool(1, |
| 1104 1, |
| 1105 histograms_.get(), |
| 1106 host_resolver_.get(), |
| 1107 &client_socket_factory_, |
| 1108 NULL); |
| 1109 |
| 1110 client_socket_factory_.set_client_socket_type( |
| 1111 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1112 |
| 1113 // Resolve an AddressList with only IPv6 addresses. |
| 1114 host_resolver_->rules()->AddIPLiteralRule( |
| 1115 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", ""); |
| 1116 |
| 1117 TestCompletionCallback callback; |
| 1118 ClientSocketHandle handle; |
| 1119 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1120 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1121 EXPECT_FALSE(handle.is_initialized()); |
| 1122 EXPECT_FALSE(handle.socket()); |
| 1123 |
| 1124 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1125 EXPECT_TRUE(handle.is_initialized()); |
| 1126 EXPECT_TRUE(handle.socket()); |
| 1127 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1128 } |
| 1129 |
| 1130 TEST_F(TCPClientSocketPoolTest, IPv4HasNoFallback) { |
| 1131 TCPClientSocketPool pool(1, |
| 1132 1, |
| 1133 histograms_.get(), |
| 1134 host_resolver_.get(), |
| 1135 &client_socket_factory_, |
| 1136 NULL); |
| 1137 |
| 1138 client_socket_factory_.set_client_socket_type( |
| 1139 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1140 |
| 1141 // Resolve an AddressList with only IPv4 addresses. |
| 1142 host_resolver_->rules()->AddIPLiteralRule( |
| 1143 "*", "1.1.1.1", ""); |
| 1144 |
| 1145 TestCompletionCallback callback; |
| 1146 ClientSocketHandle handle; |
| 1147 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1148 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1149 EXPECT_FALSE(handle.is_initialized()); |
| 1150 EXPECT_FALSE(handle.socket()); |
| 1151 |
| 1152 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1153 EXPECT_TRUE(handle.is_initialized()); |
| 1154 EXPECT_TRUE(handle.socket()); |
| 1155 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1156 } |
| 1157 |
915 } // namespace | 1158 } // namespace |
916 | 1159 |
917 } // namespace net | 1160 } // namespace net |
OLD | NEW |