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