1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/socket/websocket_transport_client_socket_pool.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/location.h"
16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/task/single_thread_task_runner.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/time/time.h"
21 #include "net/base/features.h"
22 #include "net/base/ip_endpoint.h"
23 #include "net/base/load_timing_info.h"
24 #include "net/base/load_timing_info_test_util.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/privacy_mode.h"
27 #include "net/base/proxy_chain.h"
28 #include "net/base/proxy_server.h"
29 #include "net/base/schemeful_site.h"
30 #include "net/base/test_completion_callback.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/dns/public/secure_dns_policy.h"
33 #include "net/log/net_log.h"
34 #include "net/socket/client_socket_handle.h"
35 #include "net/socket/connect_job.h"
36 #include "net/socket/connect_job_test_util.h"
37 #include "net/socket/socket_tag.h"
38 #include "net/socket/socket_test_util.h"
39 #include "net/socket/ssl_client_socket.h"
40 #include "net/socket/stream_socket.h"
41 #include "net/socket/transport_client_socket_pool_test_util.h"
42 #include "net/socket/transport_connect_job.h"
43 #include "net/socket/websocket_endpoint_lock_manager.h"
44 #include "net/test/gtest_util.h"
45 #include "net/test/test_with_task_environment.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/abseil-cpp/absl/types/optional.h"
49 #include "url/gurl.h"
50 #include "url/scheme_host_port.h"
51 #include "url/url_constants.h"
52
53 using net::test::IsError;
54 using net::test::IsOk;
55
56 namespace net {
57
58 namespace {
59
60 const int kMaxSockets = 32;
61 const int kMaxSocketsPerGroup = 6;
62 const RequestPriority kDefaultPriority = LOW;
63
ParseIP(const std::string & ip)64 IPAddress ParseIP(const std::string& ip) {
65 IPAddress address;
66 CHECK(address.AssignFromIPLiteral(ip));
67 return address;
68 }
69
70 // RunLoop doesn't support this natively but it is easy to emulate.
RunLoopForTimePeriod(base::TimeDelta period)71 void RunLoopForTimePeriod(base::TimeDelta period) {
72 base::RunLoop run_loop;
73 base::OnceClosure quit_closure(run_loop.QuitClosure());
74 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
75 FROM_HERE, std::move(quit_closure), period);
76 run_loop.Run();
77 }
78
79 class WebSocketTransportClientSocketPoolTest : public TestWithTaskEnvironment {
80 protected:
WebSocketTransportClientSocketPoolTest()81 WebSocketTransportClientSocketPoolTest()
82 : group_id_(url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
83 PrivacyMode::PRIVACY_MODE_DISABLED,
84 NetworkAnonymizationKey(),
85 SecureDnsPolicy::kAllow),
86 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()),
87 host_resolver_(std::make_unique<
88 MockHostResolver>(/*default_result=*/
89 MockHostResolverBase::RuleResolver::
90 GetLocalhostResult())),
91 client_socket_factory_(NetLog::Get()),
92 common_connect_job_params_(
93 &client_socket_factory_,
94 host_resolver_.get(),
95 /*http_auth_cache=*/nullptr,
96 /*http_auth_handler_factory=*/nullptr,
97 /*spdy_session_pool=*/nullptr,
98 /*quic_supported_versions=*/nullptr,
99 /*quic_stream_factory=*/nullptr,
100 /*proxy_delegate=*/nullptr,
101 /*http_user_agent_settings=*/nullptr,
102 /*ssl_client_context=*/nullptr,
103 /*socket_performance_watcher_factory=*/nullptr,
104 /*network_quality_estimator=*/nullptr,
105 /*net_log=*/nullptr,
106 &websocket_endpoint_lock_manager_,
107 /*http_server_properties=*/nullptr,
108 /*alpn_protos=*/nullptr,
109 /*application_settings=*/nullptr,
110 /*ignore_certificate_errors=*/nullptr),
111 pool_(kMaxSockets,
112 kMaxSocketsPerGroup,
113 ProxyChain::Direct(),
114 &common_connect_job_params_) {
115 websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
116 base::TimeDelta());
117 }
118
119 WebSocketTransportClientSocketPoolTest(
120 const WebSocketTransportClientSocketPoolTest&) = delete;
121 WebSocketTransportClientSocketPoolTest& operator=(
122 const WebSocketTransportClientSocketPoolTest&) = delete;
123
~WebSocketTransportClientSocketPoolTest()124 ~WebSocketTransportClientSocketPoolTest() override {
125 RunUntilIdle();
126 // ReleaseAllConnections() calls RunUntilIdle() after releasing each
127 // connection.
128 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
129 EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
130 }
131
RunUntilIdle()132 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
133
StartRequest(RequestPriority priority)134 int StartRequest(RequestPriority priority) {
135 return test_base_.StartRequestUsingPool(
136 &pool_, group_id_, priority, ClientSocketPool::RespectLimits::ENABLED,
137 params_);
138 }
139
GetOrderOfRequest(size_t index)140 int GetOrderOfRequest(size_t index) {
141 return test_base_.GetOrderOfRequest(index);
142 }
143
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)144 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
145 return test_base_.ReleaseOneConnection(keep_alive);
146 }
147
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)148 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
149 test_base_.ReleaseAllConnections(keep_alive);
150 }
151
request(int i)152 TestSocketRequest* request(int i) { return test_base_.request(i); }
153
requests()154 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
155 return test_base_.requests();
156 }
completion_count() const157 size_t completion_count() const { return test_base_.completion_count(); }
158
159 // |group_id_| and |params_| correspond to the same socket parameters.
160 const ClientSocketPool::GroupId group_id_;
161 scoped_refptr<ClientSocketPool::SocketParams> params_;
162 std::unique_ptr<MockHostResolver> host_resolver_;
163 MockTransportClientSocketFactory client_socket_factory_;
164 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
165 const CommonConnectJobParams common_connect_job_params_;
166 WebSocketTransportClientSocketPool pool_;
167 ClientSocketPoolTest test_base_;
168 };
169
TEST_F(WebSocketTransportClientSocketPoolTest,Basic)170 TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
171 TestCompletionCallback callback;
172 ClientSocketHandle handle;
173 int rv =
174 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
175 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
176 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
177 &pool_, NetLogWithSource());
178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
179 EXPECT_FALSE(handle.is_initialized());
180 EXPECT_FALSE(handle.socket());
181
182 EXPECT_THAT(callback.WaitForResult(), IsOk());
183 EXPECT_TRUE(handle.is_initialized());
184 EXPECT_TRUE(handle.socket());
185 TestLoadTimingInfoConnectedNotReused(handle);
186 }
187
188 // Make sure that the ConnectJob passes on its priority to its HostResolver
189 // request on Init.
TEST_F(WebSocketTransportClientSocketPoolTest,SetResolvePriorityOnInit)190 TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
191 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
192 RequestPriority priority = static_cast<RequestPriority>(i);
193 TestCompletionCallback callback;
194 ClientSocketHandle handle;
195 EXPECT_EQ(
196 ERR_IO_PENDING,
197 handle.Init(group_id_, params_,
198 absl::nullopt /* proxy_annotation_tag */, priority,
199 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
200 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
201 &pool_, NetLogWithSource()));
202 EXPECT_EQ(priority, host_resolver_->last_request_priority());
203 }
204 }
205
TEST_F(WebSocketTransportClientSocketPoolTest,InitHostResolutionFailure)206 TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
207 url::SchemeHostPort endpoint(url::kHttpScheme, "unresolvable.host.name", 80);
208 host_resolver_->rules()->AddSimulatedTimeoutFailure(endpoint.host());
209 TestCompletionCallback callback;
210 ClientSocketHandle handle;
211 EXPECT_EQ(
212 ERR_IO_PENDING,
213 handle.Init(ClientSocketPool::GroupId(
214 std::move(endpoint), PRIVACY_MODE_DISABLED,
215 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow),
216 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
217 absl::nullopt /* proxy_annotation_tag */, kDefaultPriority,
218 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
219 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
220 &pool_, NetLogWithSource()));
221 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
222 EXPECT_THAT(handle.resolve_error_info().error, IsError(ERR_DNS_TIMED_OUT));
223 EXPECT_THAT(handle.connection_attempts(),
224 testing::ElementsAre(
225 ConnectionAttempt(IPEndPoint(), ERR_NAME_NOT_RESOLVED)));
226 }
227
TEST_F(WebSocketTransportClientSocketPoolTest,InitConnectionFailure)228 TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
229 client_socket_factory_.set_default_client_socket_type(
230 MockTransportClientSocketFactory::Type::kFailing);
231 TestCompletionCallback callback;
232 ClientSocketHandle handle;
233 EXPECT_EQ(
234 ERR_IO_PENDING,
235 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
236 kDefaultPriority, SocketTag(),
237 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
238 ClientSocketPool::ProxyAuthCallback(), &pool_,
239 NetLogWithSource()));
240 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
241 EXPECT_THAT(
242 handle.connection_attempts(),
243 testing::ElementsAre(ConnectionAttempt(
244 IPEndPoint(IPAddress::IPv4Localhost(), 80), ERR_CONNECTION_FAILED)));
245
246 // Make the host resolutions complete synchronously this time.
247 host_resolver_->set_synchronous_mode(true);
248 EXPECT_EQ(
249 ERR_CONNECTION_FAILED,
250 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
251 kDefaultPriority, SocketTag(),
252 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
253 ClientSocketPool::ProxyAuthCallback(), &pool_,
254 NetLogWithSource()));
255 EXPECT_THAT(
256 handle.connection_attempts(),
257 testing::ElementsAre(ConnectionAttempt(
258 IPEndPoint(IPAddress::IPv4Localhost(), 80), ERR_CONNECTION_FAILED)));
259 }
260
TEST_F(WebSocketTransportClientSocketPoolTest,PendingRequestsFinishFifo)261 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
262 // First request finishes asynchronously.
263 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
264 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
265
266 // Make all subsequent host resolutions complete synchronously.
267 host_resolver_->set_synchronous_mode(true);
268
269 // Rest of them wait for the first socket to be released.
270 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
271 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
272 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
273 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
274 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
275
276 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
277
278 EXPECT_EQ(6, client_socket_factory_.allocation_count());
279
280 // One initial asynchronous request and then 5 pending requests.
281 EXPECT_EQ(6U, completion_count());
282
283 // The requests finish in FIFO order.
284 EXPECT_EQ(1, GetOrderOfRequest(1));
285 EXPECT_EQ(2, GetOrderOfRequest(2));
286 EXPECT_EQ(3, GetOrderOfRequest(3));
287 EXPECT_EQ(4, GetOrderOfRequest(4));
288 EXPECT_EQ(5, GetOrderOfRequest(5));
289 EXPECT_EQ(6, GetOrderOfRequest(6));
290
291 // Make sure we test order of all requests made.
292 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
293 }
294
TEST_F(WebSocketTransportClientSocketPoolTest,PendingRequests_NoKeepAlive)295 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
296 // First request finishes asynchronously.
297 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
298 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
299
300 // Make all subsequent host resolutions complete synchronously.
301 host_resolver_->set_synchronous_mode(true);
302
303 // Rest of them wait for the first socket to be released.
304 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
305 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
306 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
307 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
308 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
309
310 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
311
312 // The pending requests should finish successfully.
313 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
314 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
315 EXPECT_THAT(request(3)->WaitForResult(), IsOk());
316 EXPECT_THAT(request(4)->WaitForResult(), IsOk());
317 EXPECT_THAT(request(5)->WaitForResult(), IsOk());
318
319 EXPECT_EQ(static_cast<int>(requests()->size()),
320 client_socket_factory_.allocation_count());
321
322 // First asynchronous request, and then last 5 pending requests.
323 EXPECT_EQ(6U, completion_count());
324 }
325
326 // This test will start up a RequestSocket() and then immediately Cancel() it.
327 // The pending host resolution will eventually complete, and destroy the
328 // ClientSocketPool which will crash if the group was not cleared properly.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequestClearGroup)329 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
330 TestCompletionCallback callback;
331 ClientSocketHandle handle;
332 EXPECT_EQ(
333 ERR_IO_PENDING,
334 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
335 kDefaultPriority, SocketTag(),
336 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
337 ClientSocketPool::ProxyAuthCallback(), &pool_,
338 NetLogWithSource()));
339 handle.Reset();
340 }
341
TEST_F(WebSocketTransportClientSocketPoolTest,TwoRequestsCancelOne)342 TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
343 ClientSocketHandle handle;
344 TestCompletionCallback callback;
345 ClientSocketHandle handle2;
346 TestCompletionCallback callback2;
347
348 EXPECT_EQ(
349 ERR_IO_PENDING,
350 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
351 kDefaultPriority, SocketTag(),
352 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
353 ClientSocketPool::ProxyAuthCallback(), &pool_,
354 NetLogWithSource()));
355 EXPECT_EQ(
356 ERR_IO_PENDING,
357 handle2.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
358 kDefaultPriority, SocketTag(),
359 ClientSocketPool::RespectLimits::ENABLED,
360 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
361 &pool_, NetLogWithSource()));
362
363 handle.Reset();
364
365 EXPECT_THAT(callback2.WaitForResult(), IsOk());
366 handle2.Reset();
367 }
368
TEST_F(WebSocketTransportClientSocketPoolTest,ConnectCancelConnect)369 TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
370 client_socket_factory_.set_default_client_socket_type(
371 MockTransportClientSocketFactory::Type::kPending);
372 ClientSocketHandle handle;
373 TestCompletionCallback callback;
374 EXPECT_EQ(
375 ERR_IO_PENDING,
376 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
377 kDefaultPriority, SocketTag(),
378 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
379 ClientSocketPool::ProxyAuthCallback(), &pool_,
380 NetLogWithSource()));
381
382 handle.Reset();
383
384 TestCompletionCallback callback2;
385 EXPECT_EQ(
386 ERR_IO_PENDING,
387 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
388 kDefaultPriority, SocketTag(),
389 ClientSocketPool::RespectLimits::ENABLED,
390 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
391 &pool_, NetLogWithSource()));
392
393 host_resolver_->set_synchronous_mode(true);
394 // At this point, handle has two ConnectingSockets out for it. Due to the
395 // setting the mock resolver into synchronous mode, the host resolution for
396 // both will return in the same loop of the MessageLoop. The client socket
397 // is a pending socket, so the Connect() will asynchronously complete on the
398 // next loop of the MessageLoop. That means that the first
399 // ConnectingSocket will enter OnIOComplete, and then the second one will.
400 // If the first one is not cancelled, it will advance the load state, and
401 // then the second one will crash.
402
403 EXPECT_THAT(callback2.WaitForResult(), IsOk());
404 EXPECT_FALSE(callback.have_result());
405
406 handle.Reset();
407 }
408
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequest)409 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
410 // First request finishes asynchronously.
411 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
412 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
413
414 // Make all subsequent host resolutions complete synchronously.
415 host_resolver_->set_synchronous_mode(true);
416
417 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
418 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
419 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
420 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
421 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
422
423 // Cancel a request.
424 const size_t index_to_cancel = 2;
425 EXPECT_FALSE(request(index_to_cancel)->handle()->is_initialized());
426 request(index_to_cancel)->handle()->Reset();
427
428 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
429
430 EXPECT_EQ(5, client_socket_factory_.allocation_count());
431
432 EXPECT_EQ(1, GetOrderOfRequest(1));
433 EXPECT_EQ(2, GetOrderOfRequest(2));
434 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
435 GetOrderOfRequest(3)); // Canceled request.
436 EXPECT_EQ(3, GetOrderOfRequest(4));
437 EXPECT_EQ(4, GetOrderOfRequest(5));
438 EXPECT_EQ(5, GetOrderOfRequest(6));
439
440 // Make sure we test order of all requests made.
441 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
442 }
443
444 // Function to be used as a callback on socket request completion. It first
445 // disconnects the successfully connected socket from the first request, and
446 // then reuses the ClientSocketHandle to request another socket. The second
447 // request is expected to succeed asynchronously.
448 //
449 // |nested_callback| is called with the result of the second socket request.
RequestSocketOnComplete(const ClientSocketPool::GroupId & group_id,ClientSocketHandle * handle,WebSocketTransportClientSocketPool * pool,TestCompletionCallback * nested_callback,int first_request_result)450 void RequestSocketOnComplete(const ClientSocketPool::GroupId& group_id,
451 ClientSocketHandle* handle,
452 WebSocketTransportClientSocketPool* pool,
453 TestCompletionCallback* nested_callback,
454 int first_request_result) {
455 EXPECT_THAT(first_request_result, IsOk());
456
457 // Don't allow reuse of the socket. Disconnect it and then release it.
458 handle->socket()->Disconnect();
459 handle->Reset();
460
461 int rv = handle->Init(
462 group_id, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
463 absl::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
464 ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
465 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
467 if (ERR_IO_PENDING != rv)
468 nested_callback->callback().Run(rv);
469 }
470
471 // Tests the case where a second socket is requested in a completion callback,
472 // and the second socket connects asynchronously. Reuses the same
473 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(WebSocketTransportClientSocketPoolTest,RequestTwice)474 TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
475 ClientSocketHandle handle;
476 TestCompletionCallback second_result_callback;
477 int rv = handle.Init(
478 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
479 absl::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
480 ClientSocketPool::RespectLimits::ENABLED,
481 base::BindOnce(&RequestSocketOnComplete, group_id_, &handle, &pool_,
482 &second_result_callback),
483 ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
484 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
485 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
486
487 handle.Reset();
488 }
489
490 // Make sure that pending requests get serviced after active requests get
491 // cancelled.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelActiveRequestWithPendingRequests)492 TEST_F(WebSocketTransportClientSocketPoolTest,
493 CancelActiveRequestWithPendingRequests) {
494 client_socket_factory_.set_default_client_socket_type(
495 MockTransportClientSocketFactory::Type::kPending);
496
497 // Queue up all the requests
498 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
499 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
500 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
501 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
502 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
503 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
504 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
505 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
506 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
507
508 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
509 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
510 for (int i = 0; i < kMaxSocketsPerGroup; i++)
511 request(i)->handle()->Reset();
512
513 // Let's wait for the rest to complete now.
514 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
515 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
516 request(i)->handle()->Reset();
517 }
518
519 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
520 }
521
522 // Make sure that pending requests get serviced after active requests fail.
TEST_F(WebSocketTransportClientSocketPoolTest,FailingActiveRequestWithPendingRequests)523 TEST_F(WebSocketTransportClientSocketPoolTest,
524 FailingActiveRequestWithPendingRequests) {
525 client_socket_factory_.set_default_client_socket_type(
526 MockTransportClientSocketFactory::Type::kPendingFailing);
527
528 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
529 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
530
531 // Queue up all the requests
532 for (int i = 0; i < kNumRequests; i++)
533 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
534
535 for (int i = 0; i < kNumRequests; i++)
536 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
537 }
538
539 // The lock on the endpoint is released when a ClientSocketHandle is reset.
TEST_F(WebSocketTransportClientSocketPoolTest,LockReleasedOnHandleReset)540 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
541 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
542 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
543 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
544 EXPECT_FALSE(request(1)->handle()->is_initialized());
545 request(0)->handle()->Reset();
546 RunUntilIdle();
547 EXPECT_TRUE(request(1)->handle()->is_initialized());
548 }
549
550 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
TEST_F(WebSocketTransportClientSocketPoolTest,LockReleasedOnHandleDelete)551 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
552 TestCompletionCallback callback;
553 auto handle = std::make_unique<ClientSocketHandle>();
554 int rv =
555 handle->Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
556 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
557 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
558 &pool_, NetLogWithSource());
559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
560
561 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
562 EXPECT_THAT(callback.WaitForResult(), IsOk());
563 EXPECT_FALSE(request(0)->handle()->is_initialized());
564 handle.reset();
565 RunUntilIdle();
566 EXPECT_TRUE(request(0)->handle()->is_initialized());
567 }
568
569 // A new connection is performed when the lock on the previous connection is
570 // explicitly released.
TEST_F(WebSocketTransportClientSocketPoolTest,ConnectionProceedsOnExplicitRelease)571 TEST_F(WebSocketTransportClientSocketPoolTest,
572 ConnectionProceedsOnExplicitRelease) {
573 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
574 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
575 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
576 EXPECT_FALSE(request(1)->handle()->is_initialized());
577 WebSocketTransportClientSocketPool::UnlockEndpoint(
578 request(0)->handle(), &websocket_endpoint_lock_manager_);
579 RunUntilIdle();
580 EXPECT_TRUE(request(1)->handle()->is_initialized());
581 }
582
583 // A connection which is cancelled before completion does not block subsequent
584 // connections.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelDuringConnectionReleasesLock)585 TEST_F(WebSocketTransportClientSocketPoolTest,
586 CancelDuringConnectionReleasesLock) {
587 MockTransportClientSocketFactory::Rule rules[] = {
588 MockTransportClientSocketFactory::Rule(
589 MockTransportClientSocketFactory::Type::kStalled),
590 MockTransportClientSocketFactory::Rule(
591 MockTransportClientSocketFactory::Type::kPending)};
592
593 client_socket_factory_.SetRules(rules);
594
595 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
596 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
597 RunUntilIdle();
598 pool_.CancelRequest(group_id_, request(0)->handle(),
599 false /* cancel_connect_job */);
600 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
601 }
602
603 // Test the case of the IPv6 address stalling, and falling back to the IPv4
604 // socket which finishes first.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6FallbackSocketIPv4FinishesFirst)605 TEST_F(WebSocketTransportClientSocketPoolTest,
606 IPv6FallbackSocketIPv4FinishesFirst) {
607 MockTransportClientSocketFactory::Rule rules[] = {
608 // This is the IPv6 socket.
609 MockTransportClientSocketFactory::Rule(
610 MockTransportClientSocketFactory::Type::kStalled),
611 // This is the IPv4 socket.
612 MockTransportClientSocketFactory::Rule(
613 MockTransportClientSocketFactory::Type::kPending)};
614
615 client_socket_factory_.SetRules(rules);
616
617 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
618 host_resolver_->rules()->AddIPLiteralRule(
619 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
620
621 TestCompletionCallback callback;
622 ClientSocketHandle handle;
623 int rv =
624 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
625 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
626 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
627 &pool_, NetLogWithSource());
628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
629 EXPECT_FALSE(handle.is_initialized());
630 EXPECT_FALSE(handle.socket());
631
632 EXPECT_THAT(callback.WaitForResult(), IsOk());
633 EXPECT_TRUE(handle.is_initialized());
634 EXPECT_TRUE(handle.socket());
635 IPEndPoint endpoint;
636 handle.socket()->GetLocalAddress(&endpoint);
637 EXPECT_TRUE(endpoint.address().IsIPv4());
638 EXPECT_EQ(2, client_socket_factory_.allocation_count());
639 }
640
641 // Test the case of the IPv6 address being slow, thus falling back to trying to
642 // connect to the IPv4 address, but having the connect to the IPv6 address
643 // finish first.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6FallbackSocketIPv6FinishesFirst)644 TEST_F(WebSocketTransportClientSocketPoolTest,
645 IPv6FallbackSocketIPv6FinishesFirst) {
646 MockTransportClientSocketFactory::Rule rules[] = {
647 // This is the IPv6 socket.
648 MockTransportClientSocketFactory::Rule(
649 MockTransportClientSocketFactory::Type::kDelayed),
650 // This is the IPv4 socket.
651 MockTransportClientSocketFactory::Rule(
652 MockTransportClientSocketFactory::Type::kStalled)};
653
654 client_socket_factory_.SetRules(rules);
655 client_socket_factory_.set_delay(TransportConnectJob::kIPv6FallbackTime +
656 base::Milliseconds(50));
657
658 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
659 host_resolver_->rules()->AddIPLiteralRule(
660 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
661
662 TestCompletionCallback callback;
663 ClientSocketHandle handle;
664 int rv =
665 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
666 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
667 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
668 &pool_, NetLogWithSource());
669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
670 EXPECT_FALSE(handle.is_initialized());
671 EXPECT_FALSE(handle.socket());
672
673 EXPECT_THAT(callback.WaitForResult(), IsOk());
674 EXPECT_TRUE(handle.is_initialized());
675 EXPECT_TRUE(handle.socket());
676 IPEndPoint endpoint;
677 handle.socket()->GetLocalAddress(&endpoint);
678 EXPECT_TRUE(endpoint.address().IsIPv6());
679 EXPECT_EQ(2, client_socket_factory_.allocation_count());
680 }
681
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6NoIPv4AddressesToFallbackTo)682 TEST_F(WebSocketTransportClientSocketPoolTest,
683 IPv6NoIPv4AddressesToFallbackTo) {
684 client_socket_factory_.set_default_client_socket_type(
685 MockTransportClientSocketFactory::Type::kDelayed);
686
687 // Resolve an AddressList with only IPv6 addresses.
688 host_resolver_->rules()->AddIPLiteralRule(
689 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
690
691 TestCompletionCallback callback;
692 ClientSocketHandle handle;
693 int rv =
694 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
695 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
696 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
697 &pool_, NetLogWithSource());
698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
699 EXPECT_FALSE(handle.is_initialized());
700 EXPECT_FALSE(handle.socket());
701
702 EXPECT_THAT(callback.WaitForResult(), IsOk());
703 EXPECT_TRUE(handle.is_initialized());
704 EXPECT_TRUE(handle.socket());
705 IPEndPoint endpoint;
706 handle.socket()->GetLocalAddress(&endpoint);
707 EXPECT_TRUE(endpoint.address().IsIPv6());
708 EXPECT_EQ(1, client_socket_factory_.allocation_count());
709 }
710
TEST_F(WebSocketTransportClientSocketPoolTest,IPv4HasNoFallback)711 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
712 client_socket_factory_.set_default_client_socket_type(
713 MockTransportClientSocketFactory::Type::kDelayed);
714
715 // Resolve an AddressList with only IPv4 addresses.
716 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
717
718 TestCompletionCallback callback;
719 ClientSocketHandle handle;
720 int rv =
721 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
722 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
723 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
724 &pool_, NetLogWithSource());
725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
726 EXPECT_FALSE(handle.is_initialized());
727 EXPECT_FALSE(handle.socket());
728
729 EXPECT_THAT(callback.WaitForResult(), IsOk());
730 EXPECT_TRUE(handle.is_initialized());
731 EXPECT_TRUE(handle.socket());
732 IPEndPoint endpoint;
733 handle.socket()->GetLocalAddress(&endpoint);
734 EXPECT_TRUE(endpoint.address().IsIPv4());
735 EXPECT_EQ(1, client_socket_factory_.allocation_count());
736 }
737
738 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
739 // proceeed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6InstantFail)740 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
741 MockTransportClientSocketFactory::Rule rules[] = {
742 // First IPv6 socket.
743 MockTransportClientSocketFactory::Rule(
744 MockTransportClientSocketFactory::Type::kFailing),
745 // Second IPv6 socket.
746 MockTransportClientSocketFactory::Rule(
747 MockTransportClientSocketFactory::Type::kFailing),
748 // This is the IPv4 socket.
749 MockTransportClientSocketFactory::Rule(
750 MockTransportClientSocketFactory::Type::kSynchronous)};
751
752 client_socket_factory_.SetRules(rules);
753
754 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
755 host_resolver_->rules()->AddIPLiteralRule(
756 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
757 host_resolver_->set_synchronous_mode(true);
758 TestCompletionCallback callback;
759 ClientSocketHandle handle;
760 int rv =
761 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
762 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
763 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
764 &pool_, NetLogWithSource());
765 EXPECT_THAT(rv, IsOk());
766 ASSERT_TRUE(handle.socket());
767
768 IPEndPoint endpoint;
769 handle.socket()->GetPeerAddress(&endpoint);
770 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
771 }
772
773 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
774 // connections proceed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6RapidFail)775 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
776 MockTransportClientSocketFactory::Rule rules[] = {
777 // First IPv6 socket.
778 MockTransportClientSocketFactory::Rule(
779 MockTransportClientSocketFactory::Type::kPendingFailing),
780 // Second IPv6 socket.
781 MockTransportClientSocketFactory::Rule(
782 MockTransportClientSocketFactory::Type::kPendingFailing),
783 // This is the IPv4 socket.
784 MockTransportClientSocketFactory::Rule(
785 MockTransportClientSocketFactory::Type::kSynchronous)};
786
787 client_socket_factory_.SetRules(rules);
788
789 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
790 host_resolver_->rules()->AddIPLiteralRule(
791 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
792
793 TestCompletionCallback callback;
794 ClientSocketHandle handle;
795 int rv =
796 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
797 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
798 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
799 &pool_, NetLogWithSource());
800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
801 EXPECT_FALSE(handle.socket());
802
803 base::TimeTicks start(base::TimeTicks::Now());
804 EXPECT_THAT(callback.WaitForResult(), IsOk());
805 EXPECT_LT(base::TimeTicks::Now() - start,
806 TransportConnectJob::kIPv6FallbackTime);
807 ASSERT_TRUE(handle.socket());
808
809 IPEndPoint endpoint;
810 handle.socket()->GetPeerAddress(&endpoint);
811 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
812 }
813
814 // If two sockets connect successfully, the one which connected first wins (this
815 // can only happen if the sockets are different types, since sockets of the same
816 // type do not race).
TEST_F(WebSocketTransportClientSocketPoolTest,FirstSuccessWins)817 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
818 client_socket_factory_.set_default_client_socket_type(
819 MockTransportClientSocketFactory::Type::kTriggerable);
820
821 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
822 host_resolver_->rules()->AddIPLiteralRule(
823 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
824
825 TestCompletionCallback callback;
826 ClientSocketHandle handle;
827 int rv =
828 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
829 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
830 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
831 &pool_, NetLogWithSource());
832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
833 ASSERT_FALSE(handle.socket());
834
835 base::OnceClosure ipv6_connect_trigger =
836 client_socket_factory_.WaitForTriggerableSocketCreation();
837 base::OnceClosure ipv4_connect_trigger =
838 client_socket_factory_.WaitForTriggerableSocketCreation();
839
840 std::move(ipv4_connect_trigger).Run();
841 std::move(ipv6_connect_trigger).Run();
842
843 EXPECT_THAT(callback.WaitForResult(), IsOk());
844 ASSERT_TRUE(handle.socket());
845
846 IPEndPoint endpoint;
847 handle.socket()->GetPeerAddress(&endpoint);
848 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
849 }
850
851 // We should not report failure until all connections have failed.
TEST_F(WebSocketTransportClientSocketPoolTest,LastFailureWins)852 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
853 client_socket_factory_.set_default_client_socket_type(
854 MockTransportClientSocketFactory::Type::kDelayedFailing);
855 base::TimeDelta delay = TransportConnectJob::kIPv6FallbackTime / 3;
856 client_socket_factory_.set_delay(delay);
857
858 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
859 host_resolver_->rules()->AddIPLiteralRule("*",
860 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
861 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
862 "1.1.1.1,2.2.2.2",
863 std::string());
864
865 // Expected order of events:
866 // After 100ms: Connect to 1:abcd::3:4:ff times out
867 // After 200ms: Connect to 2:abcd::3:4:ff times out
868 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
869 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
870 // After 500ms: Connect to 2.2.2.2 times out
871
872 TestCompletionCallback callback;
873 ClientSocketHandle handle;
874 base::TimeTicks start(base::TimeTicks::Now());
875 int rv =
876 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
877 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
878 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
879 &pool_, NetLogWithSource());
880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
881
882 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
883
884 EXPECT_GE(base::TimeTicks::Now() - start, delay * 5);
885
886 // The order is slightly timing-dependent, so don't assert on the order.
887 EXPECT_THAT(handle.connection_attempts(),
888 testing::UnorderedElementsAre(
889 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
890 ERR_CONNECTION_FAILED),
891 ConnectionAttempt(IPEndPoint(ParseIP("2:abcd::3:4:ff"), 80),
892 ERR_CONNECTION_FAILED),
893 ConnectionAttempt(IPEndPoint(ParseIP("3:abcd::3:4:ff"), 80),
894 ERR_CONNECTION_FAILED),
895 ConnectionAttempt(IPEndPoint(ParseIP("4:abcd::3:4:ff"), 80),
896 ERR_CONNECTION_FAILED),
897 ConnectionAttempt(IPEndPoint(ParseIP("1.1.1.1"), 80),
898 ERR_CONNECTION_FAILED),
899 ConnectionAttempt(IPEndPoint(ParseIP("2.2.2.2"), 80),
900 ERR_CONNECTION_FAILED)));
901 }
902
903 // Test that, if an address fails due to `ERR_NETWORK_IO_SUSPENDED`, we do not
904 // try subsequent addresses.
TEST_F(WebSocketTransportClientSocketPoolTest,Suspend)905 TEST_F(WebSocketTransportClientSocketPoolTest, Suspend) {
906 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
907 host_resolver_->rules()->AddIPLiteralRule("*",
908 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
909 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
910 "1.1.1.1,2.2.2.2",
911 std::string());
912
913 // The first connection attempt will fail, after which no more will be
914 // attempted.
915 MockTransportClientSocketFactory::Rule rule(
916 MockTransportClientSocketFactory::Type::kFailing,
917 std::vector{IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80)},
918 ERR_NETWORK_IO_SUSPENDED);
919 client_socket_factory_.SetRules(base::make_span(&rule, 1u));
920
921 TestCompletionCallback callback;
922 ClientSocketHandle handle;
923 int rv =
924 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
925 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
926 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
927 &pool_, NetLogWithSource());
928 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_IO_SUSPENDED));
929 EXPECT_THAT(handle.connection_attempts(),
930 testing::ElementsAre(
931 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
932 ERR_NETWORK_IO_SUSPENDED)));
933 }
934
935 // Same as above, but with a asynchronous failure.
TEST_F(WebSocketTransportClientSocketPoolTest,SuspendAsync)936 TEST_F(WebSocketTransportClientSocketPoolTest, SuspendAsync) {
937 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
938 host_resolver_->rules()->AddIPLiteralRule("*",
939 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
940 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
941 "1.1.1.1,2.2.2.2",
942 std::string());
943
944 // The first connection attempt will fail, after which no more will be
945 // attempted.
946 MockTransportClientSocketFactory::Rule rule(
947 MockTransportClientSocketFactory::Type::kPendingFailing,
948 std::vector{IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80)},
949 ERR_NETWORK_IO_SUSPENDED);
950 client_socket_factory_.SetRules(base::make_span(&rule, 1u));
951
952 TestCompletionCallback callback;
953 ClientSocketHandle handle;
954 int rv =
955 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
956 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
957 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
958 &pool_, NetLogWithSource());
959 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_IO_SUSPENDED));
960 EXPECT_THAT(handle.connection_attempts(),
961 testing::ElementsAre(
962 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
963 ERR_NETWORK_IO_SUSPENDED)));
964 }
965
966 // Global timeout for all connects applies. This test is disabled by default
967 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
968 // want to run it.
TEST_F(WebSocketTransportClientSocketPoolTest,DISABLED_OverallTimeoutApplies)969 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
970 const base::TimeDelta connect_job_timeout =
971 TransportConnectJob::ConnectionTimeout();
972
973 client_socket_factory_.set_default_client_socket_type(
974 MockTransportClientSocketFactory::Type::kDelayedFailing);
975 client_socket_factory_.set_delay(base::Seconds(1) + connect_job_timeout / 6);
976
977 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 addresses.
978 host_resolver_->rules()->AddIPLiteralRule("*",
979 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
980 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
981 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
982 "1.1.1.1,2.2.2.2,3.3.3.3,"
983 "4.4.4.4,5.5.5.5,6.6.6.6",
984 std::string());
985
986 TestCompletionCallback callback;
987 ClientSocketHandle handle;
988
989 int rv =
990 handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
991 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
992 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
993 &pool_, NetLogWithSource());
994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
995
996 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
997 }
998
TEST_F(WebSocketTransportClientSocketPoolTest,MaxSocketsEnforced)999 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) {
1000 host_resolver_->set_synchronous_mode(true);
1001 for (int i = 0; i < kMaxSockets; ++i) {
1002 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1003 WebSocketTransportClientSocketPool::UnlockEndpoint(
1004 request(i)->handle(), &websocket_endpoint_lock_manager_);
1005 RunUntilIdle();
1006 }
1007 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1008 }
1009
TEST_F(WebSocketTransportClientSocketPoolTest,MaxSocketsEnforcedWhenPending)1010 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
1011 for (int i = 0; i < kMaxSockets + 1; ++i) {
1012 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1013 }
1014 // Now there are 32 sockets waiting to connect, and one stalled.
1015 for (int i = 0; i < kMaxSockets; ++i) {
1016 RunUntilIdle();
1017 EXPECT_TRUE(request(i)->handle()->is_initialized());
1018 EXPECT_TRUE(request(i)->handle()->socket());
1019 WebSocketTransportClientSocketPool::UnlockEndpoint(
1020 request(i)->handle(), &websocket_endpoint_lock_manager_);
1021 }
1022 // Now there are 32 sockets connected, and one stalled.
1023 RunUntilIdle();
1024 EXPECT_FALSE(request(kMaxSockets)->handle()->is_initialized());
1025 EXPECT_FALSE(request(kMaxSockets)->handle()->socket());
1026 }
1027
TEST_F(WebSocketTransportClientSocketPoolTest,StalledSocketReleased)1028 TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) {
1029 host_resolver_->set_synchronous_mode(true);
1030 for (int i = 0; i < kMaxSockets; ++i) {
1031 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1032 WebSocketTransportClientSocketPool::UnlockEndpoint(
1033 request(i)->handle(), &websocket_endpoint_lock_manager_);
1034 RunUntilIdle();
1035 }
1036
1037 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1038 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1039 EXPECT_TRUE(request(kMaxSockets)->handle()->is_initialized());
1040 EXPECT_TRUE(request(kMaxSockets)->handle()->socket());
1041 }
1042
TEST_F(WebSocketTransportClientSocketPoolTest,IsStalledTrueWhenStalled)1043 TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) {
1044 for (int i = 0; i < kMaxSockets + 1; ++i) {
1045 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1046 }
1047 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
1048 EXPECT_TRUE(pool_.IsStalled());
1049 }
1050
TEST_F(WebSocketTransportClientSocketPoolTest,CancellingPendingSocketUnstallsStalledSocket)1051 TEST_F(WebSocketTransportClientSocketPoolTest,
1052 CancellingPendingSocketUnstallsStalledSocket) {
1053 for (int i = 0; i < kMaxSockets + 1; ++i) {
1054 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1055 }
1056 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
1057 request(1)->handle()->Reset();
1058 RunUntilIdle();
1059 EXPECT_FALSE(pool_.IsStalled());
1060 }
1061
TEST_F(WebSocketTransportClientSocketPoolTest,LoadStateOfStalledSocketIsWaitingForAvailableSocket)1062 TEST_F(WebSocketTransportClientSocketPoolTest,
1063 LoadStateOfStalledSocketIsWaitingForAvailableSocket) {
1064 for (int i = 0; i < kMaxSockets + 1; ++i) {
1065 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1066 }
1067 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
1068 pool_.GetLoadState(group_id_, request(kMaxSockets)->handle()));
1069 }
1070
TEST_F(WebSocketTransportClientSocketPoolTest,CancellingStalledSocketUnstallsPool)1071 TEST_F(WebSocketTransportClientSocketPoolTest,
1072 CancellingStalledSocketUnstallsPool) {
1073 for (int i = 0; i < kMaxSockets + 1; ++i) {
1074 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1075 }
1076 request(kMaxSockets)->handle()->Reset();
1077 RunUntilIdle();
1078 EXPECT_FALSE(pool_.IsStalled());
1079 }
1080
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorFlushesPendingConnections)1081 TEST_F(WebSocketTransportClientSocketPoolTest,
1082 FlushWithErrorFlushesPendingConnections) {
1083 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1084 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1085 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_FAILED));
1086 }
1087
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorFlushesStalledConnections)1088 TEST_F(WebSocketTransportClientSocketPoolTest,
1089 FlushWithErrorFlushesStalledConnections) {
1090 for (int i = 0; i < kMaxSockets + 1; ++i) {
1091 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1092 }
1093 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1094 EXPECT_THAT(request(kMaxSockets)->WaitForResult(), IsError(ERR_FAILED));
1095 }
1096
TEST_F(WebSocketTransportClientSocketPoolTest,AfterFlushWithErrorCanMakeNewConnections)1097 TEST_F(WebSocketTransportClientSocketPoolTest,
1098 AfterFlushWithErrorCanMakeNewConnections) {
1099 for (int i = 0; i < kMaxSockets + 1; ++i) {
1100 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1101 }
1102 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1103 host_resolver_->set_synchronous_mode(true);
1104 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1105 }
1106
1107 // Deleting pending connections can release the lock on the endpoint, which can
1108 // in principle lead to other pending connections succeeding. However, when we
1109 // call FlushWithError(), everything should fail.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotCauseSuccessfulConnections)1110 TEST_F(WebSocketTransportClientSocketPoolTest,
1111 FlushWithErrorDoesNotCauseSuccessfulConnections) {
1112 host_resolver_->set_synchronous_mode(true);
1113 MockTransportClientSocketFactory::Rule first_rule[] = {
1114 // First socket
1115 MockTransportClientSocketFactory::Rule(
1116 MockTransportClientSocketFactory::Type::kPending),
1117 };
1118 client_socket_factory_.SetRules(first_rule);
1119 // The rest of the sockets will connect synchronously.
1120 client_socket_factory_.set_default_client_socket_type(
1121 MockTransportClientSocketFactory::Type::kSynchronous);
1122 for (int i = 0; i < kMaxSockets; ++i) {
1123 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1124 }
1125 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in
1126 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the
1127 // lock, they will synchronously connect.
1128 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1129 for (int i = 0; i < kMaxSockets; ++i) {
1130 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_FAILED));
1131 }
1132 }
1133
1134 // This is a regression test for the first attempted fix for
1135 // FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can
1136 // have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for
1137 // the lock at the same time.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes)1138 TEST_F(WebSocketTransportClientSocketPoolTest,
1139 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes) {
1140 host_resolver_->set_synchronous_mode(true);
1141 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have
1142 // one IPv4.
1143 std::vector<MockTransportClientSocketFactory::Rule> rules(
1144 kMaxSockets + 1, MockTransportClientSocketFactory::Rule(
1145 MockTransportClientSocketFactory::Type::kStalled));
1146 client_socket_factory_.SetRules(rules);
1147 // The rest of the sockets will connect synchronously.
1148 client_socket_factory_.set_default_client_socket_type(
1149 MockTransportClientSocketFactory::Type::kSynchronous);
1150 for (int i = 0; i < kMaxSockets; ++i) {
1151 host_resolver_->rules()->ClearRules();
1152 // Each connect job has a different IPv6 address but the same IPv4 address.
1153 // So the IPv6 connections happen in parallel but the IPv4 ones are
1154 // serialised.
1155 host_resolver_->rules()->AddIPLiteralRule("*",
1156 base::StringPrintf(
1157 "%x:abcd::3:4:ff,"
1158 "1.1.1.1",
1159 i + 1),
1160 std::string());
1161 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1162 }
1163 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
1164 // are started yet.
1165 RunLoopForTimePeriod(TransportConnectJob::kIPv6FallbackTime);
1166 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
1167 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
1168 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1169 for (int i = 0; i < kMaxSockets; ++i) {
1170 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_FAILED));
1171 }
1172 }
1173
1174 // Sockets that have had ownership transferred to a ClientSocketHandle should
1175 // not be affected by FlushWithError.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotAffectHandedOutSockets)1176 TEST_F(WebSocketTransportClientSocketPoolTest,
1177 FlushWithErrorDoesNotAffectHandedOutSockets) {
1178 host_resolver_->set_synchronous_mode(true);
1179 MockTransportClientSocketFactory::Rule rules[] = {
1180 MockTransportClientSocketFactory::Rule(
1181 MockTransportClientSocketFactory::Type::kSynchronous),
1182 MockTransportClientSocketFactory::Rule(
1183 MockTransportClientSocketFactory::Type::kStalled)};
1184 client_socket_factory_.SetRules(rules);
1185 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1186 // Socket has been "handed out".
1187 EXPECT_TRUE(request(0)->handle()->socket());
1188
1189 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1190 // Now we have one socket handed out, and one pending.
1191 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1192 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_FAILED));
1193 // Socket owned by ClientSocketHandle is unaffected:
1194 EXPECT_TRUE(request(0)->handle()->socket());
1195 // Return it to the pool (which deletes it).
1196 request(0)->handle()->Reset();
1197 }
1198
1199 // Sockets should not be leaked if CancelRequest() is called in between
1200 // SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequestReclaimsSockets)1201 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestReclaimsSockets) {
1202 host_resolver_->set_synchronous_mode(true);
1203 MockTransportClientSocketFactory::Rule rules[] = {
1204 MockTransportClientSocketFactory::Rule(
1205 MockTransportClientSocketFactory::Type::kTriggerable),
1206 MockTransportClientSocketFactory::Rule(
1207 MockTransportClientSocketFactory::Type::kSynchronous)};
1208
1209 client_socket_factory_.SetRules(rules);
1210
1211 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1212
1213 base::OnceClosure connect_trigger =
1214 client_socket_factory_.WaitForTriggerableSocketCreation();
1215
1216 std::move(connect_trigger).Run(); // Calls InvokeUserCallbackLater()
1217
1218 request(0)->handle()->Reset(); // calls CancelRequest()
1219
1220 RunUntilIdle();
1221 // We should now be able to create a new connection without blocking on the
1222 // endpoint lock.
1223 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1224 }
1225
1226 // A handshake completing and then the WebSocket closing should only release one
1227 // Endpoint, not two.
TEST_F(WebSocketTransportClientSocketPoolTest,EndpointLockIsOnlyReleasedOnce)1228 TEST_F(WebSocketTransportClientSocketPoolTest, EndpointLockIsOnlyReleasedOnce) {
1229 host_resolver_->set_synchronous_mode(true);
1230 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1231 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1232 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1233 // First socket completes handshake.
1234 WebSocketTransportClientSocketPool::UnlockEndpoint(
1235 request(0)->handle(), &websocket_endpoint_lock_manager_);
1236 RunUntilIdle();
1237 // First socket is closed.
1238 request(0)->handle()->Reset();
1239 // Second socket should have been released.
1240 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
1241 // Third socket should still be waiting for endpoint.
1242 ASSERT_FALSE(request(2)->handle()->is_initialized());
1243 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
1244 request(2)->handle()->GetLoadState());
1245 }
1246
1247 // Make sure that WebSocket requests use the correct NetworkAnonymizationKey.
TEST_F(WebSocketTransportClientSocketPoolTest,NetworkAnonymizationKey)1248 TEST_F(WebSocketTransportClientSocketPoolTest, NetworkAnonymizationKey) {
1249 const SchemefulSite kSite(GURL("https://foo.test/"));
1250 const auto kNetworkAnonymizationKey =
1251 NetworkAnonymizationKey::CreateSameSite(kSite);
1252
1253 base::test::ScopedFeatureList scoped_feature_list;
1254 scoped_feature_list.InitWithFeatures(
1255 // enabled_features
1256 {features::kPartitionConnectionsByNetworkIsolationKey,
1257 features::kSplitHostCacheByNetworkIsolationKey},
1258 // disabled_features
1259 {});
1260
1261 host_resolver_->set_ondemand_mode(true);
1262
1263 TestCompletionCallback callback;
1264 ClientSocketHandle handle;
1265 ClientSocketPool::GroupId group_id(
1266 url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
1267 PrivacyMode::PRIVACY_MODE_DISABLED, kNetworkAnonymizationKey,
1268 SecureDnsPolicy::kAllow);
1269 EXPECT_THAT(
1270 handle.Init(group_id, params_, absl::nullopt /* proxy_annotation_tag */,
1271 kDefaultPriority, SocketTag(),
1272 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1273 ClientSocketPool::ProxyAuthCallback(), &pool_,
1274 NetLogWithSource()),
1275 IsError(ERR_IO_PENDING));
1276
1277 ASSERT_EQ(1u, host_resolver_->last_id());
1278 EXPECT_EQ(kNetworkAnonymizationKey,
1279 host_resolver_->request_network_anonymization_key(1));
1280 }
1281
TEST_F(WebSocketTransportClientSocketPoolTest,TransportConnectJobWithDnsAliases)1282 TEST_F(WebSocketTransportClientSocketPoolTest,
1283 TransportConnectJobWithDnsAliases) {
1284 host_resolver_->set_synchronous_mode(true);
1285 client_socket_factory_.set_default_client_socket_type(
1286 MockTransportClientSocketFactory::Type::kSynchronous);
1287
1288 // Resolve an AddressList with DNS aliases.
1289 std::string kHostName("host");
1290 std::vector<std::string> aliases({"alias1", "alias2", kHostName});
1291 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
1292 std::move(aliases));
1293
1294 TestConnectJobDelegate test_delegate;
1295 scoped_refptr<TransportSocketParams> params =
1296 base::MakeRefCounted<TransportSocketParams>(
1297 HostPortPair(kHostName, 80), NetworkAnonymizationKey(),
1298 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1299 /*supported_alpns=*/base::flat_set<std::string>());
1300
1301 TransportConnectJob transport_connect_job(
1302 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
1303 &test_delegate, nullptr /* net_log */);
1304
1305 test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
1306 true /* expect_sync_result */);
1307
1308 // Verify that the elements of the alias list are those from the
1309 // parameter vector.
1310 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1311 testing::ElementsAre("alias1", "alias2", kHostName));
1312 }
1313
TEST_F(WebSocketTransportClientSocketPoolTest,TransportConnectJobWithNoAdditionalDnsAliases)1314 TEST_F(WebSocketTransportClientSocketPoolTest,
1315 TransportConnectJobWithNoAdditionalDnsAliases) {
1316 host_resolver_->set_synchronous_mode(true);
1317 client_socket_factory_.set_default_client_socket_type(
1318 MockTransportClientSocketFactory::Type::kSynchronous);
1319
1320 // Resolve an AddressList without additional DNS aliases. (The parameter
1321 // is an empty vector.)
1322 std::string kHostName("host");
1323 std::vector<std::string> aliases;
1324 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
1325 std::move(aliases));
1326
1327 TestConnectJobDelegate test_delegate;
1328 scoped_refptr<TransportSocketParams> params =
1329 base::MakeRefCounted<TransportSocketParams>(
1330 HostPortPair(kHostName, 80), NetworkAnonymizationKey(),
1331 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1332 /*supported_alpns=*/base::flat_set<std::string>());
1333
1334 TransportConnectJob transport_connect_job(
1335 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
1336 &test_delegate, nullptr /* net_log */);
1337
1338 test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
1339 true /* expect_sync_result */);
1340
1341 // Verify that the alias list only contains kHostName.
1342 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1343 testing::ElementsAre(kHostName));
1344 }
1345
TEST_F(WebSocketTransportClientSocketPoolTest,LoadState)1346 TEST_F(WebSocketTransportClientSocketPoolTest, LoadState) {
1347 host_resolver_->rules()->AddRule("v6-only.test", "1:abcd::3:4:ff");
1348 host_resolver_->rules()->AddRule("v6-and-v4.test", "1:abcd::3:4:ff,2.2.2.2");
1349 host_resolver_->set_ondemand_mode(true);
1350
1351 client_socket_factory_.set_default_client_socket_type(
1352 MockTransportClientSocketFactory::Type::kDelayedFailing);
1353
1354 auto params_v6_only = base::MakeRefCounted<TransportSocketParams>(
1355 HostPortPair("v6-only.test", 80), NetworkAnonymizationKey(),
1356 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1357 /*supported_alpns=*/base::flat_set<std::string>());
1358 auto params_v6_and_v4 = base::MakeRefCounted<TransportSocketParams>(
1359 HostPortPair("v6-and-v4.test", 80), NetworkAnonymizationKey(),
1360 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1361 /*supported_alpns=*/base::flat_set<std::string>());
1362
1363 // v6-only.test will first block on DNS.
1364 TestConnectJobDelegate test_delegate_v6_only;
1365 TransportConnectJob connect_job_v6_only(
1366 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
1367 params_v6_only, &test_delegate_v6_only, /*net_log=*/nullptr);
1368 EXPECT_THAT(connect_job_v6_only.Connect(), test::IsError(ERR_IO_PENDING));
1369 EXPECT_THAT(connect_job_v6_only.GetLoadState(), LOAD_STATE_RESOLVING_HOST);
1370
1371 // When DNS is resolved, it should block on making a connection.
1372 host_resolver_->ResolveOnlyRequestNow();
1373 base::RunLoop().RunUntilIdle();
1374 EXPECT_THAT(connect_job_v6_only.GetLoadState(), LOAD_STATE_CONNECTING);
1375
1376 // v6-and-v4.test will also first block on DNS.
1377 TestConnectJobDelegate test_delegate_v6_and_v4;
1378 TransportConnectJob connect_job_v6_and_v4(
1379 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
1380 params_v6_and_v4, &test_delegate_v6_and_v4, /*net_log=*/nullptr);
1381 EXPECT_THAT(connect_job_v6_and_v4.Connect(), test::IsError(ERR_IO_PENDING));
1382 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(), LOAD_STATE_RESOLVING_HOST);
1383
1384 // When DNS is resolved, it should attempt to connect to the IPv6 address, but
1385 // `connect_job_v6_only` holds the lock.
1386 host_resolver_->ResolveOnlyRequestNow();
1387 RunUntilIdle();
1388 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(),
1389 LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET);
1390
1391 // After the IPv6 fallback timeout, it should attempt to connect to the IPv4
1392 // address. This lock is available, so `GetLoadState` should report it is now
1393 // actively connecting.
1394 RunLoopForTimePeriod(TransportConnectJob::kIPv6FallbackTime +
1395 base::Milliseconds(50));
1396 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(), LOAD_STATE_CONNECTING);
1397 }
1398
1399 } // namespace
1400
1401 } // namespace net
1402