1 // Copyright 2012 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 <stdint.h>
6
7 #include <optional>
8 #include <string_view>
9 #include <utility>
10 #include <vector>
11
12 #include "base/check_op.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "base/functional/callback_helpers.h"
16 #include "base/location.h"
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/notreached.h"
21 #include "base/run_loop.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/stringprintf.h"
24 #include "base/task/single_thread_task_runner.h"
25 #include "base/test/scoped_feature_list.h"
26 #include "base/threading/platform_thread.h"
27 #include "base/time/time.h"
28 #include "base/values.h"
29 #include "net/base/features.h"
30 #include "net/base/host_port_pair.h"
31 #include "net/base/load_timing_info.h"
32 #include "net/base/load_timing_info_test_util.h"
33 #include "net/base/net_errors.h"
34 #include "net/base/network_anonymization_key.h"
35 #include "net/base/privacy_mode.h"
36 #include "net/base/proxy_chain.h"
37 #include "net/base/proxy_string_util.h"
38 #include "net/base/request_priority.h"
39 #include "net/base/schemeful_site.h"
40 #include "net/base/test_completion_callback.h"
41 #include "net/dns/public/resolve_error_info.h"
42 #include "net/dns/public/secure_dns_policy.h"
43 #include "net/http/http_response_headers.h"
44 #include "net/http/http_response_info.h"
45 #include "net/log/net_log.h"
46 #include "net/log/net_log_event_type.h"
47 #include "net/log/net_log_source.h"
48 #include "net/log/net_log_source_type.h"
49 #include "net/log/test_net_log.h"
50 #include "net/log/test_net_log_util.h"
51 #include "net/socket/client_socket_factory.h"
52 #include "net/socket/client_socket_handle.h"
53 #include "net/socket/connect_job_factory.h"
54 #include "net/socket/datagram_client_socket.h"
55 #include "net/socket/socket_performance_watcher.h"
56 #include "net/socket/socket_tag.h"
57 #include "net/socket/socket_test_util.h"
58 #include "net/socket/ssl_client_socket.h"
59 #include "net/socket/stream_socket.h"
60 #include "net/socket/transport_client_socket_pool.h"
61 #include "net/socket/transport_connect_job.h"
62 #include "net/ssl/ssl_cert_request_info.h"
63 #include "net/ssl/ssl_config.h"
64 #include "net/test/gtest_util.h"
65 #include "net/test/test_with_task_environment.h"
66 #include "net/traffic_annotation/network_traffic_annotation.h"
67 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
68 #include "testing/gmock/include/gmock/gmock.h"
69 #include "testing/gtest/include/gtest/gtest.h"
70 #include "url/scheme_host_port.h"
71 #include "url/url_constants.h"
72
73 using net::test::IsError;
74 using net::test::IsOk;
75
76 using ::testing::Invoke;
77 using ::testing::Return;
78
79 namespace net {
80
81 namespace {
82
83 const int kDefaultMaxSockets = 4;
84 const int kDefaultMaxSocketsPerGroup = 2;
85 constexpr base::TimeDelta kUnusedIdleSocketTimeout = base::Seconds(10);
86
TestGroupId(std::string_view host,int port=80,std::string_view scheme=url::kHttpScheme,PrivacyMode privacy_mode=PrivacyMode::PRIVACY_MODE_DISABLED,NetworkAnonymizationKey network_anonymization_key=NetworkAnonymizationKey ())87 ClientSocketPool::GroupId TestGroupId(
88 std::string_view host,
89 int port = 80,
90 std::string_view scheme = url::kHttpScheme,
91 PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED,
92 NetworkAnonymizationKey network_anonymization_key =
93 NetworkAnonymizationKey()) {
94 return ClientSocketPool::GroupId(url::SchemeHostPort(scheme, host, port),
95 privacy_mode, network_anonymization_key,
96 SecureDnsPolicy::kAllow,
97 /*disable_cert_network_fetches=*/false);
98 }
99
100 // Make sure |handle| sets load times correctly when it has been assigned a
101 // reused socket.
TestLoadTimingInfoConnectedReused(const ClientSocketHandle & handle)102 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
103 LoadTimingInfo load_timing_info;
104 // Only pass true in as |is_reused|, as in general, HttpStream types should
105 // have stricter concepts of reuse than socket pools.
106 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
107
108 EXPECT_EQ(true, load_timing_info.socket_reused);
109 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
110
111 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
112 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
113 }
114
115 // Make sure |handle| sets load times correctly when it has been assigned a
116 // fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
117 // of a connection where |is_reused| is false may consider the connection
118 // reused.
TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle & handle)119 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
120 EXPECT_FALSE(handle.is_reused());
121
122 LoadTimingInfo load_timing_info;
123 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
124
125 EXPECT_FALSE(load_timing_info.socket_reused);
126 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
127
128 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
129 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
130 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
131
132 TestLoadTimingInfoConnectedReused(handle);
133 }
134
135 // Make sure |handle| sets load times correctly, in the case that it does not
136 // currently have a socket.
TestLoadTimingInfoNotConnected(const ClientSocketHandle & handle)137 void TestLoadTimingInfoNotConnected(const ClientSocketHandle& handle) {
138 // Should only be set to true once a socket is assigned, if at all.
139 EXPECT_FALSE(handle.is_reused());
140
141 LoadTimingInfo load_timing_info;
142 EXPECT_FALSE(handle.GetLoadTimingInfo(false, &load_timing_info));
143
144 EXPECT_FALSE(load_timing_info.socket_reused);
145 EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
146
147 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
148 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
149 }
150
151 class MockClientSocket : public StreamSocket {
152 public:
MockClientSocket(net::NetLog * net_log)153 explicit MockClientSocket(net::NetLog* net_log)
154 : net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {}
155
156 MockClientSocket(const MockClientSocket&) = delete;
157 MockClientSocket& operator=(const MockClientSocket&) = delete;
158
159 // Sets whether the socket has unread data. If true, the next call to Read()
160 // will return 1 byte and IsConnectedAndIdle() will return false.
set_has_unread_data(bool has_unread_data)161 void set_has_unread_data(bool has_unread_data) {
162 has_unread_data_ = has_unread_data;
163 }
164
165 // Socket implementation.
Read(IOBuffer *,int len,CompletionOnceCallback)166 int Read(IOBuffer* /* buf */,
167 int len,
168 CompletionOnceCallback /* callback */) override {
169 if (has_unread_data_ && len > 0) {
170 has_unread_data_ = false;
171 was_used_to_convey_data_ = true;
172 return 1;
173 }
174 return ERR_UNEXPECTED;
175 }
176
Write(IOBuffer *,int len,CompletionOnceCallback,const NetworkTrafficAnnotationTag &)177 int Write(
178 IOBuffer* /* buf */,
179 int len,
180 CompletionOnceCallback /* callback */,
181 const NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
182 was_used_to_convey_data_ = true;
183 return len;
184 }
SetReceiveBufferSize(int32_t size)185 int SetReceiveBufferSize(int32_t size) override { return OK; }
SetSendBufferSize(int32_t size)186 int SetSendBufferSize(int32_t size) override { return OK; }
187
188 // StreamSocket implementation.
Connect(CompletionOnceCallback callback)189 int Connect(CompletionOnceCallback callback) override {
190 connected_ = true;
191 return OK;
192 }
193
Disconnect()194 void Disconnect() override { connected_ = false; }
IsConnected() const195 bool IsConnected() const override { return connected_; }
IsConnectedAndIdle() const196 bool IsConnectedAndIdle() const override {
197 return connected_ && !has_unread_data_;
198 }
199
GetPeerAddress(IPEndPoint *) const200 int GetPeerAddress(IPEndPoint* /* address */) const override {
201 return ERR_UNEXPECTED;
202 }
203
GetLocalAddress(IPEndPoint *) const204 int GetLocalAddress(IPEndPoint* /* address */) const override {
205 return ERR_UNEXPECTED;
206 }
207
NetLog() const208 const NetLogWithSource& NetLog() const override { return net_log_; }
209
WasEverUsed() const210 bool WasEverUsed() const override { return was_used_to_convey_data_; }
GetNegotiatedProtocol() const211 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
GetSSLInfo(SSLInfo * ssl_info)212 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
GetTotalReceivedBytes() const213 int64_t GetTotalReceivedBytes() const override {
214 NOTIMPLEMENTED();
215 return 0;
216 }
ApplySocketTag(const SocketTag & tag)217 void ApplySocketTag(const SocketTag& tag) override {}
218
219 private:
220 bool connected_ = false;
221 bool has_unread_data_ = false;
222 NetLogWithSource net_log_;
223 bool was_used_to_convey_data_ = false;
224 };
225
226 class TestConnectJob;
227
228 class MockClientSocketFactory : public ClientSocketFactory {
229 public:
230 MockClientSocketFactory() = default;
231
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)232 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
233 DatagramSocket::BindType bind_type,
234 NetLog* net_log,
235 const NetLogSource& source) override {
236 NOTREACHED();
237 return nullptr;
238 }
239
CreateTransportClientSocket(const AddressList & addresses,std::unique_ptr<SocketPerformanceWatcher>,NetworkQualityEstimator *,NetLog *,const NetLogSource &)240 std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
241 const AddressList& addresses,
242 std::unique_ptr<
243 SocketPerformanceWatcher> /* socket_performance_watcher */,
244 NetworkQualityEstimator* /* network_quality_estimator */,
245 NetLog* /* net_log */,
246 const NetLogSource& /*source*/) override {
247 allocation_count_++;
248 return nullptr;
249 }
250
CreateSSLClientSocket(SSLClientContext * context,std::unique_ptr<StreamSocket> stream_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config)251 std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
252 SSLClientContext* context,
253 std::unique_ptr<StreamSocket> stream_socket,
254 const HostPortPair& host_and_port,
255 const SSLConfig& ssl_config) override {
256 NOTIMPLEMENTED();
257 return nullptr;
258 }
259
WaitForSignal(TestConnectJob * job)260 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
261
262 void SignalJobs();
263
264 void SignalJob(size_t job);
265
266 void SetJobLoadState(size_t job, LoadState load_state);
267
268 // Sets the HasConnectionEstablished value of the specified job to true,
269 // without invoking the callback.
270 void SetJobHasEstablishedConnection(size_t job);
271
allocation_count() const272 int allocation_count() const { return allocation_count_; }
273
274 private:
275 int allocation_count_ = 0;
276 std::vector<raw_ptr<TestConnectJob, VectorExperimental>> waiting_jobs_;
277 };
278
279 class TestConnectJob : public ConnectJob {
280 public:
281 enum JobType {
282 kMockJob,
283 kMockFailingJob,
284 kMockPendingJob,
285 kMockPendingFailingJob,
286 kMockWaitingJob,
287
288 // Certificate errors return a socket in addition to an error code.
289 kMockCertErrorJob,
290 kMockPendingCertErrorJob,
291
292 kMockAdditionalErrorStateJob,
293 kMockPendingAdditionalErrorStateJob,
294 kMockUnreadDataJob,
295
296 kMockAuthChallengeOnceJob,
297 kMockAuthChallengeTwiceJob,
298 kMockAuthChallengeOnceFailingJob,
299 kMockAuthChallengeTwiceFailingJob,
300 };
301
302 // The kMockPendingJob uses a slight delay before allowing the connect
303 // to complete.
304 static const int kPendingConnectDelay = 2;
305
TestConnectJob(JobType job_type,RequestPriority request_priority,SocketTag socket_tag,base::TimeDelta timeout_duration,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate,MockClientSocketFactory * client_socket_factory)306 TestConnectJob(JobType job_type,
307 RequestPriority request_priority,
308 SocketTag socket_tag,
309 base::TimeDelta timeout_duration,
310 const CommonConnectJobParams* common_connect_job_params,
311 ConnectJob::Delegate* delegate,
312 MockClientSocketFactory* client_socket_factory)
313 : ConnectJob(request_priority,
314 socket_tag,
315 timeout_duration,
316 common_connect_job_params,
317 delegate,
318 nullptr /* net_log */,
319 NetLogSourceType::TRANSPORT_CONNECT_JOB,
320 NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
321 job_type_(job_type),
322 client_socket_factory_(client_socket_factory) {}
323
324 TestConnectJob(const TestConnectJob&) = delete;
325 TestConnectJob& operator=(const TestConnectJob&) = delete;
326
Signal()327 void Signal() {
328 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
329 }
330
set_load_state(LoadState load_state)331 void set_load_state(LoadState load_state) { load_state_ = load_state; }
332
set_has_established_connection()333 void set_has_established_connection() {
334 DCHECK(!has_established_connection_);
335 has_established_connection_ = true;
336 }
337
338 // From ConnectJob:
339
GetLoadState() const340 LoadState GetLoadState() const override { return load_state_; }
341
HasEstablishedConnection() const342 bool HasEstablishedConnection() const override {
343 return has_established_connection_;
344 }
345
GetResolveErrorInfo() const346 ResolveErrorInfo GetResolveErrorInfo() const override {
347 return ResolveErrorInfo(OK);
348 }
349
IsSSLError() const350 bool IsSSLError() const override { return store_additional_error_state_; }
351
GetCertRequestInfo()352 scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override {
353 if (store_additional_error_state_) {
354 return base::MakeRefCounted<SSLCertRequestInfo>();
355 }
356 return nullptr;
357 }
358
359 private:
360 // From ConnectJob:
361
ConnectInternal()362 int ConnectInternal() override {
363 AddressList ignored;
364 client_socket_factory_->CreateTransportClientSocket(
365 ignored, nullptr, nullptr, nullptr, NetLogSource());
366 switch (job_type_) {
367 case kMockJob:
368 return DoConnect(true /* successful */, false /* sync */,
369 false /* cert_error */);
370 case kMockFailingJob:
371 return DoConnect(false /* error */, false /* sync */,
372 false /* cert_error */);
373 case kMockPendingJob:
374 set_load_state(LOAD_STATE_CONNECTING);
375
376 // Depending on execution timings, posting a delayed task can result
377 // in the task getting executed the at the earliest possible
378 // opportunity or only after returning once from the message loop and
379 // then a second call into the message loop. In order to make behavior
380 // more deterministic, we change the default delay to 2ms. This should
381 // always require us to wait for the second call into the message loop.
382 //
383 // N.B. The correct fix for this and similar timing problems is to
384 // abstract time for the purpose of unittests. Unfortunately, we have
385 // a lot of third-party components that directly call the various
386 // time functions, so this change would be rather invasive.
387 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
388 FROM_HERE,
389 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
390 weak_factory_.GetWeakPtr(), true /* successful */,
391 true /* async */, false /* cert_error */),
392 base::Milliseconds(kPendingConnectDelay));
393 return ERR_IO_PENDING;
394 case kMockPendingFailingJob:
395 set_load_state(LOAD_STATE_CONNECTING);
396 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
397 FROM_HERE,
398 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
399 weak_factory_.GetWeakPtr(), false /* error */,
400 true /* async */, false /* cert_error */),
401 base::Milliseconds(2));
402 return ERR_IO_PENDING;
403 case kMockWaitingJob:
404 set_load_state(LOAD_STATE_CONNECTING);
405 client_socket_factory_->WaitForSignal(this);
406 waiting_success_ = true;
407 return ERR_IO_PENDING;
408 case kMockCertErrorJob:
409 return DoConnect(false /* error */, false /* sync */,
410 true /* cert_error */);
411 case kMockPendingCertErrorJob:
412 set_load_state(LOAD_STATE_CONNECTING);
413 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
414 FROM_HERE,
415 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
416 weak_factory_.GetWeakPtr(), false /* error */,
417 true /* async */, true /* cert_error */),
418 base::Milliseconds(2));
419 return ERR_IO_PENDING;
420 case kMockAdditionalErrorStateJob:
421 store_additional_error_state_ = true;
422 return DoConnect(false /* error */, false /* sync */,
423 false /* cert_error */);
424 case kMockPendingAdditionalErrorStateJob:
425 set_load_state(LOAD_STATE_CONNECTING);
426 store_additional_error_state_ = true;
427 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
428 FROM_HERE,
429 base::BindOnce(base::IgnoreResult(&TestConnectJob::DoConnect),
430 weak_factory_.GetWeakPtr(), false /* error */,
431 true /* async */, false /* cert_error */),
432 base::Milliseconds(2));
433 return ERR_IO_PENDING;
434 case kMockUnreadDataJob: {
435 int ret = DoConnect(true /* successful */, false /* sync */,
436 false /* cert_error */);
437 static_cast<MockClientSocket*>(socket())->set_has_unread_data(true);
438 return ret;
439 }
440 case kMockAuthChallengeOnceJob:
441 set_load_state(LOAD_STATE_CONNECTING);
442 DoAdvanceAuthChallenge(1, true /* succeed_after_last_challenge */);
443 return ERR_IO_PENDING;
444 case kMockAuthChallengeTwiceJob:
445 set_load_state(LOAD_STATE_CONNECTING);
446 DoAdvanceAuthChallenge(2, true /* succeed_after_last_challenge */);
447 return ERR_IO_PENDING;
448 case kMockAuthChallengeOnceFailingJob:
449 set_load_state(LOAD_STATE_CONNECTING);
450 DoAdvanceAuthChallenge(1, false /* succeed_after_last_challenge */);
451 return ERR_IO_PENDING;
452 case kMockAuthChallengeTwiceFailingJob:
453 set_load_state(LOAD_STATE_CONNECTING);
454 DoAdvanceAuthChallenge(2, false /* succeed_after_last_challenge */);
455 return ERR_IO_PENDING;
456 default:
457 NOTREACHED();
458 SetSocket(std::unique_ptr<StreamSocket>(), std::nullopt);
459 return ERR_FAILED;
460 }
461 }
462
ChangePriorityInternal(RequestPriority priority)463 void ChangePriorityInternal(RequestPriority priority) override {}
464
DoConnect(bool succeed,bool was_async,bool cert_error)465 int DoConnect(bool succeed, bool was_async, bool cert_error) {
466 int result = OK;
467 has_established_connection_ = true;
468 if (succeed) {
469 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
470 std::nullopt);
471 socket()->Connect(CompletionOnceCallback());
472 } else if (cert_error) {
473 SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
474 std::nullopt);
475 result = ERR_CERT_COMMON_NAME_INVALID;
476 } else {
477 result = ERR_CONNECTION_FAILED;
478 SetSocket(std::unique_ptr<StreamSocket>(), std::nullopt);
479 }
480
481 if (was_async) {
482 NotifyDelegateOfCompletion(result);
483 }
484 return result;
485 }
486
DoAdvanceAuthChallenge(int remaining_challenges,bool succeed_after_last_challenge)487 void DoAdvanceAuthChallenge(int remaining_challenges,
488 bool succeed_after_last_challenge) {
489 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
490 FROM_HERE,
491 base::BindOnce(&TestConnectJob::InvokeNextProxyAuthCallback,
492 weak_factory_.GetWeakPtr(), remaining_challenges,
493 succeed_after_last_challenge));
494 }
495
InvokeNextProxyAuthCallback(int remaining_challenges,bool succeed_after_last_challenge)496 void InvokeNextProxyAuthCallback(int remaining_challenges,
497 bool succeed_after_last_challenge) {
498 set_load_state(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
499 if (remaining_challenges == 0) {
500 DoConnect(succeed_after_last_challenge, true /* was_async */,
501 false /* cert_error */);
502 return;
503 }
504
505 // Integration tests make sure HttpResponseInfo and HttpAuthController work.
506 // The auth tests here are just focused on ConnectJob bookkeeping.
507 HttpResponseInfo info;
508 NotifyDelegateOfProxyAuth(
509 info, nullptr /* http_auth_controller */,
510 base::BindOnce(&TestConnectJob::DoAdvanceAuthChallenge,
511 weak_factory_.GetWeakPtr(), remaining_challenges - 1,
512 succeed_after_last_challenge));
513 }
514
515 bool waiting_success_;
516 const JobType job_type_;
517 const raw_ptr<MockClientSocketFactory> client_socket_factory_;
518 LoadState load_state_ = LOAD_STATE_IDLE;
519 bool has_established_connection_ = false;
520 bool store_additional_error_state_ = false;
521
522 base::WeakPtrFactory<TestConnectJob> weak_factory_{this};
523 };
524
525 class TestConnectJobFactory : public ConnectJobFactory {
526 public:
TestConnectJobFactory(MockClientSocketFactory * client_socket_factory)527 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
528 : client_socket_factory_(client_socket_factory) {}
529
530 TestConnectJobFactory(const TestConnectJobFactory&) = delete;
531 TestConnectJobFactory& operator=(const TestConnectJobFactory&) = delete;
532
533 ~TestConnectJobFactory() override = default;
534
set_job_type(TestConnectJob::JobType job_type)535 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
536
set_job_types(std::list<TestConnectJob::JobType> * job_types)537 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
538 job_types_ = job_types;
539 CHECK(!job_types_->empty());
540 }
541
set_timeout_duration(base::TimeDelta timeout_duration)542 void set_timeout_duration(base::TimeDelta timeout_duration) {
543 timeout_duration_ = timeout_duration;
544 }
545
546 // ConnectJobFactory implementation.
547
CreateConnectJob(Endpoint endpoint,const ProxyChain & proxy_chain,const std::optional<NetworkTrafficAnnotationTag> & proxy_annotation_tag,const std::vector<SSLConfig::CertAndStatus> & allowed_bad_certs,ConnectJobFactory::AlpnMode alpn_mode,bool force_tunnel,PrivacyMode privacy_mode,const OnHostResolutionCallback & resolution_callback,RequestPriority request_priority,SocketTag socket_tag,const NetworkAnonymizationKey & network_anonymization_key,SecureDnsPolicy secure_dns_policy,bool disable_cert_network_fetches,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate) const548 std::unique_ptr<ConnectJob> CreateConnectJob(
549 Endpoint endpoint,
550 const ProxyChain& proxy_chain,
551 const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
552 const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
553 ConnectJobFactory::AlpnMode alpn_mode,
554 bool force_tunnel,
555 PrivacyMode privacy_mode,
556 const OnHostResolutionCallback& resolution_callback,
557 RequestPriority request_priority,
558 SocketTag socket_tag,
559 const NetworkAnonymizationKey& network_anonymization_key,
560 SecureDnsPolicy secure_dns_policy,
561 bool disable_cert_network_fetches,
562 const CommonConnectJobParams* common_connect_job_params,
563 ConnectJob::Delegate* delegate) const override {
564 EXPECT_TRUE(!job_types_ || !job_types_->empty());
565 TestConnectJob::JobType job_type = job_type_;
566 if (job_types_ && !job_types_->empty()) {
567 job_type = job_types_->front();
568 job_types_->pop_front();
569 }
570 return std::make_unique<TestConnectJob>(
571 job_type, request_priority, socket_tag, timeout_duration_,
572 common_connect_job_params, delegate, client_socket_factory_);
573 }
574
575 private:
576 TestConnectJob::JobType job_type_ = TestConnectJob::kMockJob;
577 raw_ptr<std::list<TestConnectJob::JobType>> job_types_ = nullptr;
578 base::TimeDelta timeout_duration_;
579 const raw_ptr<MockClientSocketFactory> client_socket_factory_;
580 };
581
582 } // namespace
583
584 namespace {
585
SignalJobs()586 void MockClientSocketFactory::SignalJobs() {
587 for (TestConnectJob* waiting_job : waiting_jobs_) {
588 waiting_job->Signal();
589 }
590 waiting_jobs_.clear();
591 }
592
SignalJob(size_t job)593 void MockClientSocketFactory::SignalJob(size_t job) {
594 ASSERT_LT(job, waiting_jobs_.size());
595 waiting_jobs_[job]->Signal();
596 waiting_jobs_.erase(waiting_jobs_.begin() + job);
597 }
598
SetJobLoadState(size_t job,LoadState load_state)599 void MockClientSocketFactory::SetJobLoadState(size_t job,
600 LoadState load_state) {
601 ASSERT_LT(job, waiting_jobs_.size());
602 waiting_jobs_[job]->set_load_state(load_state);
603 }
604
SetJobHasEstablishedConnection(size_t job)605 void MockClientSocketFactory::SetJobHasEstablishedConnection(size_t job) {
606 ASSERT_LT(job, waiting_jobs_.size());
607 waiting_jobs_[job]->set_has_established_connection();
608 }
609
610 class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
611 protected:
ClientSocketPoolBaseTest()612 ClientSocketPoolBaseTest()
613 : TestWithTaskEnvironment(
614 base::test::TaskEnvironment::TimeSource::MOCK_TIME),
615 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) {
616 connect_backup_jobs_enabled_ =
617 TransportClientSocketPool::connect_backup_jobs_enabled();
618 TransportClientSocketPool::set_connect_backup_jobs_enabled(true);
619 }
620
~ClientSocketPoolBaseTest()621 ~ClientSocketPoolBaseTest() override {
622 TransportClientSocketPool::set_connect_backup_jobs_enabled(
623 connect_backup_jobs_enabled_);
624 }
625
CreatePool(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)626 void CreatePool(int max_sockets,
627 int max_sockets_per_group,
628 bool enable_backup_connect_jobs = false) {
629 CreatePoolWithIdleTimeouts(max_sockets, max_sockets_per_group,
630 kUnusedIdleSocketTimeout,
631 ClientSocketPool::used_idle_socket_timeout(),
632 enable_backup_connect_jobs);
633 }
634
CreatePoolWithIdleTimeouts(int max_sockets,int max_sockets_per_group,base::TimeDelta unused_idle_socket_timeout,base::TimeDelta used_idle_socket_timeout,bool enable_backup_connect_jobs=false,ProxyChain proxy_chain=ProxyChain::Direct ())635 void CreatePoolWithIdleTimeouts(
636 int max_sockets,
637 int max_sockets_per_group,
638 base::TimeDelta unused_idle_socket_timeout,
639 base::TimeDelta used_idle_socket_timeout,
640 bool enable_backup_connect_jobs = false,
641 ProxyChain proxy_chain = ProxyChain::Direct()) {
642 DCHECK(!pool_.get());
643 std::unique_ptr<TestConnectJobFactory> connect_job_factory =
644 std::make_unique<TestConnectJobFactory>(&client_socket_factory_);
645 connect_job_factory_ = connect_job_factory.get();
646 pool_ = TransportClientSocketPool::CreateForTesting(
647 max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
648 used_idle_socket_timeout, proxy_chain, /*is_for_websockets=*/false,
649 &common_connect_job_params_, std::move(connect_job_factory),
650 nullptr /* ssl_config_service */, enable_backup_connect_jobs);
651 }
652
StartRequestWithIgnoreLimits(const ClientSocketPool::GroupId & group_id,RequestPriority priority,ClientSocketPool::RespectLimits respect_limits)653 int StartRequestWithIgnoreLimits(
654 const ClientSocketPool::GroupId& group_id,
655 RequestPriority priority,
656 ClientSocketPool::RespectLimits respect_limits) {
657 return test_base_.StartRequestUsingPool(pool_.get(), group_id, priority,
658 respect_limits, params_);
659 }
660
StartRequest(const ClientSocketPool::GroupId & group_id,RequestPriority priority)661 int StartRequest(const ClientSocketPool::GroupId& group_id,
662 RequestPriority priority) {
663 return StartRequestWithIgnoreLimits(
664 group_id, priority, ClientSocketPool::RespectLimits::ENABLED);
665 }
666
GetOrderOfRequest(size_t index) const667 int GetOrderOfRequest(size_t index) const {
668 return test_base_.GetOrderOfRequest(index);
669 }
670
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)671 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
672 return test_base_.ReleaseOneConnection(keep_alive);
673 }
674
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)675 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
676 test_base_.ReleaseAllConnections(keep_alive);
677 }
678
679 // Expects a single NetLogEventType::SOCKET_POOL_CLOSING_SOCKET in |net_log_|.
680 // It should be logged for the provided source and have the indicated reason.
ExpectSocketClosedWithReason(NetLogSource expected_source,const char * expected_reason)681 void ExpectSocketClosedWithReason(NetLogSource expected_source,
682 const char* expected_reason) {
683 auto entries = net_log_observer_.GetEntriesForSourceWithType(
684 expected_source, NetLogEventType::SOCKET_POOL_CLOSING_SOCKET,
685 NetLogEventPhase::NONE);
686 ASSERT_EQ(1u, entries.size());
687 ASSERT_TRUE(entries[0].HasParams());
688 const std::string* reason = entries[0].params.FindString("reason");
689 ASSERT_TRUE(reason);
690 EXPECT_EQ(expected_reason, *reason);
691 }
692
request(int i)693 TestSocketRequest* request(int i) { return test_base_.request(i); }
requests_size() const694 size_t requests_size() const { return test_base_.requests_size(); }
requests()695 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
696 return test_base_.requests();
697 }
698 // Only counts the requests that get sockets asynchronously;
699 // synchronous completions are not registered by this count.
completion_count() const700 size_t completion_count() const { return test_base_.completion_count(); }
701
702 const CommonConnectJobParams common_connect_job_params_{
703 /*client_socket_factory=*/nullptr,
704 /*host_resolver=*/nullptr,
705 /*http_auth_cache=*/nullptr,
706 /*http_auth_handler_factory=*/nullptr,
707 /*spdy_session_pool=*/nullptr,
708 /*quic_supported_versions=*/nullptr,
709 /*quic_session_pool=*/nullptr,
710 /*proxy_delegate=*/nullptr,
711 /*http_user_agent_settings=*/nullptr,
712 /*ssl_client_context=*/nullptr,
713 /*socket_performance_watcher_factory=*/nullptr,
714 /*network_quality_estimator=*/nullptr,
715 NetLog::Get(),
716 /*websocket_endpoint_lock_manager=*/nullptr,
717 /*http_server_properties=*/nullptr,
718 /*alpn_protos=*/nullptr,
719 /*application_settings=*/nullptr,
720 /*ignore_certificate_errors=*/nullptr,
721 /*early_data_enabled=*/nullptr};
722 bool connect_backup_jobs_enabled_;
723 MockClientSocketFactory client_socket_factory_;
724 RecordingNetLogObserver net_log_observer_;
725
726 // These parameters are never actually used to create a TransportConnectJob.
727 scoped_refptr<ClientSocketPool::SocketParams> params_;
728
729 // Must outlive `connect_job_factory_`
730 std::unique_ptr<TransportClientSocketPool> pool_;
731
732 raw_ptr<TestConnectJobFactory> connect_job_factory_;
733 ClientSocketPoolTest test_base_;
734 };
735
TEST_F(ClientSocketPoolBaseTest,BasicSynchronous)736 TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
737 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
738
739 TestCompletionCallback callback;
740 ClientSocketHandle handle;
741 NetLogWithSource net_log_with_source =
742 NetLogWithSource::Make(NetLogSourceType::NONE);
743
744 TestLoadTimingInfoNotConnected(handle);
745
746 EXPECT_EQ(OK, handle.Init(
747 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
748 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
749 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
750 pool_.get(), net_log_with_source));
751 EXPECT_TRUE(handle.is_initialized());
752 EXPECT_TRUE(handle.socket());
753 TestLoadTimingInfoConnectedNotReused(handle);
754
755 handle.Reset();
756 TestLoadTimingInfoNotConnected(handle);
757
758 auto entries =
759 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
760
761 EXPECT_EQ(5u, entries.size());
762 EXPECT_TRUE(LogContainsEvent(
763 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
764 NetLogEventPhase::NONE));
765 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
766 EXPECT_TRUE(LogContainsEvent(
767 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
768 NetLogEventPhase::NONE));
769 EXPECT_TRUE(LogContainsEvent(entries, 3,
770 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
771 NetLogEventPhase::NONE));
772 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
773 }
774
TEST_F(ClientSocketPoolBaseTest,InitConnectionFailure)775 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
776 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
777
778 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
779 NetLogWithSource net_log_with_source =
780 NetLogWithSource::Make(NetLogSourceType::NONE);
781
782 ClientSocketHandle handle;
783 TestCompletionCallback callback;
784 // Set the additional error state members to ensure that they get cleared.
785 handle.set_is_ssl_error(true);
786 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
787 EXPECT_EQ(
788 ERR_CONNECTION_FAILED,
789 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
790 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
791 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
792 pool_.get(), net_log_with_source));
793 EXPECT_FALSE(handle.socket());
794 EXPECT_FALSE(handle.is_ssl_error());
795 EXPECT_FALSE(handle.ssl_cert_request_info());
796 TestLoadTimingInfoNotConnected(handle);
797
798 auto entries =
799 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
800
801 EXPECT_EQ(4u, entries.size());
802 EXPECT_TRUE(LogContainsEvent(
803 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
804 NetLogEventPhase::NONE));
805 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
806 EXPECT_TRUE(LogContainsEvent(
807 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
808 NetLogEventPhase::NONE));
809 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
810 }
811
812 // Test releasing an open socket into the socket pool, telling the socket pool
813 // to close the socket.
TEST_F(ClientSocketPoolBaseTest,ReleaseAndCloseConnection)814 TEST_F(ClientSocketPoolBaseTest, ReleaseAndCloseConnection) {
815 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
816
817 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
818 ASSERT_TRUE(request(0)->handle()->socket());
819 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
820 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
821
822 EXPECT_EQ(0, pool_->IdleSocketCount());
823 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
824
825 ExpectSocketClosedWithReason(
826 source, TransportClientSocketPool::kClosedConnectionReturnedToPool);
827 }
828
TEST_F(ClientSocketPoolBaseTest,SocketWithUnreadDataReturnedToPool)829 TEST_F(ClientSocketPoolBaseTest, SocketWithUnreadDataReturnedToPool) {
830 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
831 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
832
833 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
834 ASSERT_TRUE(request(0)->handle()->socket());
835 net::NetLogSource source = request(0)->handle()->socket()->NetLog().source();
836 EXPECT_TRUE(request(0)->handle()->socket()->IsConnected());
837 EXPECT_FALSE(request(0)->handle()->socket()->IsConnectedAndIdle());
838 ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE);
839
840 EXPECT_EQ(0, pool_->IdleSocketCount());
841 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
842
843 ExpectSocketClosedWithReason(
844 source, TransportClientSocketPool::kDataReceivedUnexpectedly);
845 }
846
847 // Make sure different groups do not share sockets.
TEST_F(ClientSocketPoolBaseTest,GroupSeparation)848 TEST_F(ClientSocketPoolBaseTest, GroupSeparation) {
849 base::test::ScopedFeatureList feature_list;
850 feature_list.InitAndEnableFeature(
851 features::kPartitionConnectionsByNetworkIsolationKey);
852
853 CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */);
854
855 const HostPortPair kHostPortPairs[] = {
856 {"a", 80},
857 {"a", 443},
858 {"b", 80},
859 };
860
861 const char* const kSchemes[] = {
862 url::kHttpScheme,
863 url::kHttpsScheme,
864 };
865
866 const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED,
867 PrivacyMode::PRIVACY_MODE_ENABLED};
868
869 const SchemefulSite kSiteA(GURL("http://a.test/"));
870 const SchemefulSite kSiteB(GURL("http://b.test/"));
871 const NetworkAnonymizationKey kNetworkAnonymizationKeys[] = {
872 NetworkAnonymizationKey::CreateSameSite(kSiteA),
873 NetworkAnonymizationKey::CreateSameSite(kSiteB),
874 };
875
876 const SecureDnsPolicy kSecureDnsPolicys[] = {SecureDnsPolicy::kAllow,
877 SecureDnsPolicy::kDisable};
878
879 int total_idle_sockets = 0;
880
881 // Walk through each GroupId, making sure that requesting a socket for one
882 // group does not return a previously connected socket for another group.
883 for (const auto& host_port_pair : kHostPortPairs) {
884 SCOPED_TRACE(host_port_pair.ToString());
885 for (const char* scheme : kSchemes) {
886 SCOPED_TRACE(scheme);
887 for (const auto& privacy_mode : kPrivacyModes) {
888 SCOPED_TRACE(privacy_mode);
889 for (const auto& network_anonymization_key :
890 kNetworkAnonymizationKeys) {
891 SCOPED_TRACE(network_anonymization_key.ToDebugString());
892 for (const auto& secure_dns_policy : kSecureDnsPolicys) {
893 SCOPED_TRACE(static_cast<int>(secure_dns_policy));
894
895 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
896
897 ClientSocketPool::GroupId group_id(
898 url::SchemeHostPort(scheme, host_port_pair.host(),
899 host_port_pair.port()),
900 privacy_mode, network_anonymization_key, secure_dns_policy,
901 /*disable_cert_network_fetches=*/false);
902
903 EXPECT_FALSE(pool_->HasGroupForTesting(group_id));
904
905 TestCompletionCallback callback;
906 ClientSocketHandle handle;
907
908 // Since the group is empty, requesting a socket should not complete
909 // synchronously.
910 EXPECT_THAT(handle.Init(group_id, params_, std::nullopt,
911 DEFAULT_PRIORITY, SocketTag(),
912 ClientSocketPool::RespectLimits::ENABLED,
913 callback.callback(),
914 ClientSocketPool::ProxyAuthCallback(),
915 pool_.get(), NetLogWithSource()),
916 IsError(ERR_IO_PENDING));
917 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
918 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
919
920 EXPECT_THAT(callback.WaitForResult(), IsOk());
921 EXPECT_TRUE(handle.socket());
922 EXPECT_TRUE(pool_->HasGroupForTesting(group_id));
923 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
924
925 // Return socket to pool.
926 handle.Reset();
927 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
928
929 // Requesting a socket again should return the same socket as
930 // before, so should complete synchronously.
931 EXPECT_THAT(handle.Init(group_id, params_, std::nullopt,
932 DEFAULT_PRIORITY, SocketTag(),
933 ClientSocketPool::RespectLimits::ENABLED,
934 callback.callback(),
935 ClientSocketPool::ProxyAuthCallback(),
936 pool_.get(), NetLogWithSource()),
937 IsOk());
938 EXPECT_TRUE(handle.socket());
939 EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount());
940
941 // Return socket to pool again.
942 handle.Reset();
943 EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount());
944
945 ++total_idle_sockets;
946 }
947 }
948 }
949 }
950 }
951 }
952
TEST_F(ClientSocketPoolBaseTest,TotalLimit)953 TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
954 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
955
956 // TODO(eroman): Check that the NetLog contains this event.
957
958 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
959 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
960 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
961 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY), IsOk());
962
963 EXPECT_EQ(static_cast<int>(requests_size()),
964 client_socket_factory_.allocation_count());
965 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
966
967 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
968 IsError(ERR_IO_PENDING));
969 EXPECT_THAT(StartRequest(TestGroupId("f"), DEFAULT_PRIORITY),
970 IsError(ERR_IO_PENDING));
971 EXPECT_THAT(StartRequest(TestGroupId("g"), DEFAULT_PRIORITY),
972 IsError(ERR_IO_PENDING));
973
974 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
975
976 EXPECT_EQ(static_cast<int>(requests_size()),
977 client_socket_factory_.allocation_count());
978 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
979
980 EXPECT_EQ(1, GetOrderOfRequest(1));
981 EXPECT_EQ(2, GetOrderOfRequest(2));
982 EXPECT_EQ(3, GetOrderOfRequest(3));
983 EXPECT_EQ(4, GetOrderOfRequest(4));
984 EXPECT_EQ(5, GetOrderOfRequest(5));
985 EXPECT_EQ(6, GetOrderOfRequest(6));
986 EXPECT_EQ(7, GetOrderOfRequest(7));
987
988 // Make sure we test order of all requests made.
989 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
990 }
991
TEST_F(ClientSocketPoolBaseTest,TotalLimitReachedNewGroup)992 TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
993 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
994
995 // TODO(eroman): Check that the NetLog contains this event.
996
997 // Reach all limits: max total sockets, and max sockets per group.
998 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
999 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1000 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1001 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1002
1003 EXPECT_EQ(static_cast<int>(requests_size()),
1004 client_socket_factory_.allocation_count());
1005 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1006
1007 // Now create a new group and verify that we don't starve it.
1008 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1009 IsError(ERR_IO_PENDING));
1010
1011 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1012
1013 EXPECT_EQ(static_cast<int>(requests_size()),
1014 client_socket_factory_.allocation_count());
1015 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1016
1017 EXPECT_EQ(1, GetOrderOfRequest(1));
1018 EXPECT_EQ(2, GetOrderOfRequest(2));
1019 EXPECT_EQ(3, GetOrderOfRequest(3));
1020 EXPECT_EQ(4, GetOrderOfRequest(4));
1021 EXPECT_EQ(5, GetOrderOfRequest(5));
1022
1023 // Make sure we test order of all requests made.
1024 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1025 }
1026
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsPriority)1027 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
1028 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1029
1030 EXPECT_THAT(StartRequest(TestGroupId("b"), LOWEST), IsOk());
1031 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsOk());
1032 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1033 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1034
1035 EXPECT_EQ(static_cast<int>(requests_size()),
1036 client_socket_factory_.allocation_count());
1037
1038 EXPECT_THAT(StartRequest(TestGroupId("c"), LOWEST), IsError(ERR_IO_PENDING));
1039 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1040 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1041
1042 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1043
1044 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1045
1046 // First 4 requests don't have to wait, and finish in order.
1047 EXPECT_EQ(1, GetOrderOfRequest(1));
1048 EXPECT_EQ(2, GetOrderOfRequest(2));
1049 EXPECT_EQ(3, GetOrderOfRequest(3));
1050 EXPECT_EQ(4, GetOrderOfRequest(4));
1051
1052 // Request ("b", HIGHEST) has the highest priority, then (TestGroupId("a"),
1053 // MEDIUM), and then ("c", LOWEST).
1054 EXPECT_EQ(7, GetOrderOfRequest(5));
1055 EXPECT_EQ(6, GetOrderOfRequest(6));
1056 EXPECT_EQ(5, GetOrderOfRequest(7));
1057
1058 // Make sure we test order of all requests made.
1059 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1060 }
1061
1062 // Test reprioritizing a request before completion doesn't interfere with
1063 // its completion.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeOne)1064 TEST_F(ClientSocketPoolBaseTest, ReprioritizeOne) {
1065 CreatePool(kDefaultMaxSockets, 1);
1066
1067 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1068 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1069 EXPECT_TRUE(request(0)->handle()->socket());
1070 EXPECT_FALSE(request(1)->handle()->socket());
1071
1072 request(1)->handle()->SetPriority(HIGHEST);
1073
1074 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1075
1076 EXPECT_TRUE(request(1)->handle()->socket());
1077 }
1078
1079 // Reprioritize a request up past another one and make sure that changes the
1080 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpReorder)1081 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpReorder) {
1082 CreatePool(kDefaultMaxSockets, 1);
1083
1084 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1085 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1086 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1087 EXPECT_TRUE(request(0)->handle()->socket());
1088 EXPECT_FALSE(request(1)->handle()->socket());
1089 EXPECT_FALSE(request(2)->handle()->socket());
1090
1091 request(2)->handle()->SetPriority(HIGHEST);
1092
1093 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1094
1095 EXPECT_EQ(1, GetOrderOfRequest(1));
1096 EXPECT_EQ(3, GetOrderOfRequest(2));
1097 EXPECT_EQ(2, GetOrderOfRequest(3));
1098 }
1099
1100 // Reprioritize a request without changing relative priorities and check
1101 // that the order doesn't change.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeUpNoReorder)1102 TEST_F(ClientSocketPoolBaseTest, ReprioritizeUpNoReorder) {
1103 CreatePool(kDefaultMaxSockets, 1);
1104
1105 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1106 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1107 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1108 EXPECT_TRUE(request(0)->handle()->socket());
1109 EXPECT_FALSE(request(1)->handle()->socket());
1110 EXPECT_FALSE(request(2)->handle()->socket());
1111
1112 request(2)->handle()->SetPriority(MEDIUM);
1113
1114 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1115
1116 EXPECT_EQ(1, GetOrderOfRequest(1));
1117 EXPECT_EQ(2, GetOrderOfRequest(2));
1118 EXPECT_EQ(3, GetOrderOfRequest(3));
1119 }
1120
1121 // Reprioritize a request past down another one and make sure that changes the
1122 // completion order.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeDownReorder)1123 TEST_F(ClientSocketPoolBaseTest, ReprioritizeDownReorder) {
1124 CreatePool(kDefaultMaxSockets, 1);
1125
1126 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1127 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1128 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1129 EXPECT_TRUE(request(0)->handle()->socket());
1130 EXPECT_FALSE(request(1)->handle()->socket());
1131 EXPECT_FALSE(request(2)->handle()->socket());
1132
1133 request(1)->handle()->SetPriority(LOW);
1134
1135 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1136
1137 EXPECT_EQ(1, GetOrderOfRequest(1));
1138 EXPECT_EQ(3, GetOrderOfRequest(2));
1139 EXPECT_EQ(2, GetOrderOfRequest(3));
1140 }
1141
1142 // Reprioritize a request to the same level as another and confirm it is
1143 // put after the old request.
TEST_F(ClientSocketPoolBaseTest,ReprioritizeResetFIFO)1144 TEST_F(ClientSocketPoolBaseTest, ReprioritizeResetFIFO) {
1145 CreatePool(kDefaultMaxSockets, 1);
1146
1147 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(OK));
1148 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1149 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1150 EXPECT_TRUE(request(0)->handle()->socket());
1151 EXPECT_FALSE(request(1)->handle()->socket());
1152 EXPECT_FALSE(request(2)->handle()->socket());
1153
1154 request(1)->handle()->SetPriority(MEDIUM);
1155
1156 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1157
1158 EXPECT_EQ(1, GetOrderOfRequest(1));
1159 EXPECT_EQ(3, GetOrderOfRequest(2));
1160 EXPECT_EQ(2, GetOrderOfRequest(3));
1161 }
1162
TEST_F(ClientSocketPoolBaseTest,TotalLimitRespectsGroupLimit)1163 TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
1164 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1165
1166 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsOk());
1167 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsOk());
1168 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsOk());
1169 EXPECT_THAT(StartRequest(TestGroupId("b"), MEDIUM), IsOk());
1170
1171 EXPECT_EQ(static_cast<int>(requests_size()),
1172 client_socket_factory_.allocation_count());
1173
1174 EXPECT_THAT(StartRequest(TestGroupId("c"), MEDIUM), IsError(ERR_IO_PENDING));
1175 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1176 EXPECT_THAT(StartRequest(TestGroupId("b"), HIGHEST), IsError(ERR_IO_PENDING));
1177
1178 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1179
1180 EXPECT_EQ(static_cast<int>(requests_size()),
1181 client_socket_factory_.allocation_count());
1182 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
1183
1184 // First 4 requests don't have to wait, and finish in order.
1185 EXPECT_EQ(1, GetOrderOfRequest(1));
1186 EXPECT_EQ(2, GetOrderOfRequest(2));
1187 EXPECT_EQ(3, GetOrderOfRequest(3));
1188 EXPECT_EQ(4, GetOrderOfRequest(4));
1189
1190 // Request ("b", 7) has the highest priority, but we can't make new socket for
1191 // group "b", because it has reached the per-group limit. Then we make
1192 // socket for ("c", 6), because it has higher priority than ("a", 4),
1193 // and we still can't make a socket for group "b".
1194 EXPECT_EQ(5, GetOrderOfRequest(5));
1195 EXPECT_EQ(6, GetOrderOfRequest(6));
1196 EXPECT_EQ(7, GetOrderOfRequest(7));
1197
1198 // Make sure we test order of all requests made.
1199 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1200 }
1201
1202 // Make sure that we count connecting sockets against the total limit.
TEST_F(ClientSocketPoolBaseTest,TotalLimitCountsConnectingSockets)1203 TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1204 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1205
1206 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1207 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
1208 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY), IsOk());
1209
1210 // Create one asynchronous request.
1211 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1212 EXPECT_THAT(StartRequest(TestGroupId("d"), DEFAULT_PRIORITY),
1213 IsError(ERR_IO_PENDING));
1214
1215 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1216 // actually become pending until 2ms after they have been created. In order
1217 // to flush all tasks, we need to wait so that we know there are no
1218 // soon-to-be-pending tasks waiting.
1219 FastForwardBy(base::Milliseconds(10));
1220
1221 // The next synchronous request should wait for its turn.
1222 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1223 EXPECT_THAT(StartRequest(TestGroupId("e"), DEFAULT_PRIORITY),
1224 IsError(ERR_IO_PENDING));
1225
1226 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1227
1228 EXPECT_EQ(static_cast<int>(requests_size()),
1229 client_socket_factory_.allocation_count());
1230
1231 EXPECT_EQ(1, GetOrderOfRequest(1));
1232 EXPECT_EQ(2, GetOrderOfRequest(2));
1233 EXPECT_EQ(3, GetOrderOfRequest(3));
1234 EXPECT_EQ(4, GetOrderOfRequest(4));
1235 EXPECT_EQ(5, GetOrderOfRequest(5));
1236
1237 // Make sure we test order of all requests made.
1238 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
1239 }
1240
TEST_F(ClientSocketPoolBaseTest,CorrectlyCountStalledGroups)1241 TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1242 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1243 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1244
1245 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1246 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1247 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1248 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1249
1250 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1251
1252 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1253
1254 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY),
1255 IsError(ERR_IO_PENDING));
1256 EXPECT_THAT(StartRequest(TestGroupId("c"), DEFAULT_PRIORITY),
1257 IsError(ERR_IO_PENDING));
1258
1259 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1260
1261 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1262 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1263 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1264 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1265 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1266 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1267 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1268 }
1269
TEST_F(ClientSocketPoolBaseTest,StallAndThenCancelAndTriggerAvailableSocket)1270 TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1271 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1272 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1273
1274 TestCompletionCallback callback;
1275 ClientSocketHandle stalled_handle;
1276 EXPECT_EQ(ERR_IO_PENDING,
1277 stalled_handle.Init(
1278 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1279 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1280 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1281 pool_.get(), NetLogWithSource()));
1282
1283 ClientSocketHandle handles[4];
1284 for (auto& handle : handles) {
1285 EXPECT_EQ(
1286 ERR_IO_PENDING,
1287 handle.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
1288 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1289 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1290 pool_.get(), NetLogWithSource()));
1291 }
1292
1293 // One will be stalled, cancel all the handles now.
1294 // This should hit the OnAvailableSocketSlot() code where we previously had
1295 // stalled groups, but no longer have any.
1296 for (auto& handle : handles) {
1297 handle.Reset();
1298 }
1299 }
1300
TEST_F(ClientSocketPoolBaseTest,CancelStalledSocketAtSocketLimit)1301 TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
1302 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1303 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1304
1305 {
1306 ClientSocketHandle handles[kDefaultMaxSockets];
1307 TestCompletionCallback callbacks[kDefaultMaxSockets];
1308 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1309 EXPECT_EQ(OK, handles[i].Init(TestGroupId("a" + base::NumberToString(i)),
1310 params_, std::nullopt, DEFAULT_PRIORITY,
1311 SocketTag(),
1312 ClientSocketPool::RespectLimits::ENABLED,
1313 callbacks[i].callback(),
1314 ClientSocketPool::ProxyAuthCallback(),
1315 pool_.get(), NetLogWithSource()));
1316 }
1317
1318 // Force a stalled group.
1319 ClientSocketHandle stalled_handle;
1320 TestCompletionCallback callback;
1321 EXPECT_EQ(ERR_IO_PENDING,
1322 stalled_handle.Init(
1323 TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
1324 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1325 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1326 pool_.get(), NetLogWithSource()));
1327
1328 // Cancel the stalled request.
1329 stalled_handle.Reset();
1330
1331 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1332 EXPECT_EQ(0, pool_->IdleSocketCount());
1333
1334 // Dropping out of scope will close all handles and return them to idle.
1335 }
1336
1337 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1338 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1339 }
1340
TEST_F(ClientSocketPoolBaseTest,CancelPendingSocketAtSocketLimit)1341 TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1342 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1343 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1344
1345 {
1346 ClientSocketHandle handles[kDefaultMaxSockets];
1347 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1348 TestCompletionCallback callback;
1349 EXPECT_EQ(ERR_IO_PENDING,
1350 handles[i].Init(
1351 TestGroupId("a" + base::NumberToString(i)), params_,
1352 std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1353 ClientSocketPool::RespectLimits::ENABLED,
1354 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1355 pool_.get(), NetLogWithSource()));
1356 }
1357
1358 // Force a stalled group.
1359 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1360 ClientSocketHandle stalled_handle;
1361 TestCompletionCallback callback;
1362 EXPECT_EQ(ERR_IO_PENDING,
1363 stalled_handle.Init(
1364 TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
1365 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1366 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1367 pool_.get(), NetLogWithSource()));
1368
1369 // Since it is stalled, it should have no connect jobs.
1370 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1371 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1372 TestGroupId("foo")));
1373 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1374 TestGroupId("foo")));
1375
1376 // Cancel the stalled request.
1377 handles[0].Reset();
1378
1379 // Now we should have a connect job.
1380 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1381 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1382 TestGroupId("foo")));
1383 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1384 TestGroupId("foo")));
1385
1386 // The stalled socket should connect.
1387 EXPECT_THAT(callback.WaitForResult(), IsOk());
1388
1389 EXPECT_EQ(kDefaultMaxSockets + 1,
1390 client_socket_factory_.allocation_count());
1391 EXPECT_EQ(0, pool_->IdleSocketCount());
1392 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo")));
1393 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
1394 TestGroupId("foo")));
1395 EXPECT_EQ(0u, pool_->NumUnassignedConnectJobsInGroupForTesting(
1396 TestGroupId("foo")));
1397
1398 // Dropping out of scope will close all handles and return them to idle.
1399 }
1400
1401 EXPECT_EQ(1, pool_->IdleSocketCount());
1402 }
1403
TEST_F(ClientSocketPoolBaseTest,WaitForStalledSocketAtSocketLimit)1404 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1405 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1406 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1407
1408 ClientSocketHandle stalled_handle;
1409 TestCompletionCallback callback;
1410 {
1411 EXPECT_FALSE(pool_->IsStalled());
1412 ClientSocketHandle handles[kDefaultMaxSockets];
1413 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1414 EXPECT_EQ(
1415 OK, handles[i].Init(
1416 TestGroupId(base::StringPrintf("take-2-%d", i)), params_,
1417 std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1418 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1419 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1420 NetLogWithSource()));
1421 }
1422
1423 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1424 EXPECT_EQ(0, pool_->IdleSocketCount());
1425 EXPECT_FALSE(pool_->IsStalled());
1426
1427 // Now we will hit the socket limit.
1428 EXPECT_EQ(ERR_IO_PENDING,
1429 stalled_handle.Init(
1430 TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
1431 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1432 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1433 pool_.get(), NetLogWithSource()));
1434 EXPECT_TRUE(pool_->IsStalled());
1435
1436 // Dropping out of scope will close all handles and return them to idle.
1437 }
1438
1439 // But if we wait for it, the released idle sockets will be closed in
1440 // preference of the waiting request.
1441 EXPECT_THAT(callback.WaitForResult(), IsOk());
1442
1443 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1444 EXPECT_EQ(3, pool_->IdleSocketCount());
1445 }
1446
1447 // Regression test for http://crbug.com/40952.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketAtSocketLimitDeleteGroup)1448 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1449 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1450 true /* enable_backup_connect_jobs */);
1451 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1452
1453 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1454 ClientSocketHandle handle;
1455 TestCompletionCallback callback;
1456 EXPECT_EQ(
1457 OK,
1458 handle.Init(TestGroupId("a" + base::NumberToString(i)), params_,
1459 std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1460 ClientSocketPool::RespectLimits::ENABLED,
1461 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1462 pool_.get(), NetLogWithSource()));
1463 }
1464
1465 // Flush all the DoReleaseSocket tasks.
1466 base::RunLoop().RunUntilIdle();
1467
1468 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1469 // reuse a socket.
1470 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1471 ClientSocketHandle handle;
1472 TestCompletionCallback callback;
1473
1474 // "a0" is special here, since it should be the first entry in the sorted map,
1475 // which is the one which we would close an idle socket for. We shouldn't
1476 // close an idle socket though, since we should reuse the idle socket.
1477 EXPECT_EQ(OK, handle.Init(
1478 TestGroupId("a0"), params_, std::nullopt, DEFAULT_PRIORITY,
1479 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1480 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1481 pool_.get(), NetLogWithSource()));
1482
1483 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1484 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1485 }
1486
TEST_F(ClientSocketPoolBaseTest,PendingRequests)1487 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1488 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1489
1490 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1491 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1492 EXPECT_THAT(StartRequest(TestGroupId("a"), IDLE), IsError(ERR_IO_PENDING));
1493 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1494 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1495 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1496 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1497 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1498
1499 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1500 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1501 client_socket_factory_.allocation_count());
1502 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup, completion_count());
1503
1504 EXPECT_EQ(1, GetOrderOfRequest(1));
1505 EXPECT_EQ(2, GetOrderOfRequest(2));
1506 EXPECT_EQ(8, GetOrderOfRequest(3));
1507 EXPECT_EQ(6, GetOrderOfRequest(4));
1508 EXPECT_EQ(4, GetOrderOfRequest(5));
1509 EXPECT_EQ(3, GetOrderOfRequest(6));
1510 EXPECT_EQ(5, GetOrderOfRequest(7));
1511 EXPECT_EQ(7, GetOrderOfRequest(8));
1512
1513 // Make sure we test order of all requests made.
1514 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1515 }
1516
TEST_F(ClientSocketPoolBaseTest,PendingRequests_NoKeepAlive)1517 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1519
1520 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1521 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1522 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1523 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1524 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1525 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1526 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1527
1528 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1529
1530 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1531 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1532 }
1533
1534 EXPECT_EQ(static_cast<int>(requests_size()),
1535 client_socket_factory_.allocation_count());
1536 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup, completion_count());
1537 }
1538
TEST_F(ClientSocketPoolBaseTest,ResetAndCloseSocket)1539 TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) {
1540 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1541
1542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1543 ClientSocketHandle handle;
1544 TestCompletionCallback callback;
1545 EXPECT_EQ(
1546 ERR_IO_PENDING,
1547 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1548 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1549 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1550 pool_.get(), NetLogWithSource()));
1551
1552 EXPECT_THAT(callback.WaitForResult(), IsOk());
1553 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1554 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1555 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
1556 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1557
1558 handle.ResetAndCloseSocket();
1559 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1560 }
1561
1562 // This test will start up a socket request and then call Reset() on the handle.
1563 // The pending ConnectJob should not be destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestKeepsConnectJob)1564 TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) {
1565 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1566
1567 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1568 ClientSocketHandle handle;
1569 TestCompletionCallback callback;
1570 EXPECT_EQ(
1571 ERR_IO_PENDING,
1572 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1573 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1574 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1575 pool_.get(), NetLogWithSource()));
1576 handle.Reset();
1577 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1578 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1579 }
1580
1581 // This test will start up a socket request and then call ResetAndCloseSocket()
1582 // on the handle. The pending ConnectJob or connected socket should be
1583 // destroyed.
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocket)1584 TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) {
1585 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1586
1587 // When true, the socket connects before it's canceled.
1588 for (bool cancel_when_callback_pending : {false, true}) {
1589 if (cancel_when_callback_pending) {
1590 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1591 } else {
1592 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1593 }
1594 ClientSocketHandle handle;
1595 TestCompletionCallback callback;
1596 EXPECT_EQ(
1597 ERR_IO_PENDING,
1598 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1599 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1600 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1601 pool_.get(), NetLogWithSource()));
1602 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1603 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1604
1605 if (cancel_when_callback_pending) {
1606 client_socket_factory_.SignalJobs();
1607 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1608 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1609 }
1610
1611 handle.ResetAndCloseSocket();
1612 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1613 }
1614 }
1615
TEST_F(ClientSocketPoolBaseTest,CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs)1616 TEST_F(ClientSocketPoolBaseTest,
1617 CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) {
1618 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1619
1620 // When true, the sockets connect before they're canceled.
1621 for (bool cancel_when_callback_pending : {false, true}) {
1622 if (cancel_when_callback_pending) {
1623 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1624 } else {
1625 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1626 }
1627
1628 std::vector<std::unique_ptr<ClientSocketHandle>> handles;
1629 TestCompletionCallback callback;
1630 // Make |kDefaultMaxSockets + 1| socket requests.
1631 for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) {
1632 std::unique_ptr<ClientSocketHandle> handle =
1633 std::make_unique<ClientSocketHandle>();
1634 EXPECT_EQ(ERR_IO_PENDING,
1635 handle->Init(
1636 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1637 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1638 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1639 pool_.get(), NetLogWithSource()));
1640 handles.push_back(std::move(handle));
1641 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1642 EXPECT_EQ(
1643 static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)),
1644 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1645 }
1646
1647 if (cancel_when_callback_pending) {
1648 client_socket_factory_.SignalJobs();
1649 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1650 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1651 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1652 }
1653
1654 // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob
1655 // or close a socket, since there are more requests than ConnectJobs or
1656 // sockets.
1657 handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket();
1658 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1659 if (cancel_when_callback_pending) {
1660 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1661 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1662 } else {
1663 EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup),
1664 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1665 }
1666
1667 // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob
1668 // or close a socket.
1669 for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) {
1670 handles[i]->ResetAndCloseSocket();
1671 if (i > 0) {
1672 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1673 if (cancel_when_callback_pending) {
1674 EXPECT_EQ(i,
1675 pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1676 } else {
1677 EXPECT_EQ(static_cast<size_t>(i),
1678 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1679 }
1680 } else {
1681 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
1682 }
1683 }
1684 }
1685 }
1686
TEST_F(ClientSocketPoolBaseTest,ConnectCancelConnect)1687 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1688 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1689
1690 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1691 ClientSocketHandle handle;
1692 TestCompletionCallback callback;
1693
1694 EXPECT_EQ(
1695 ERR_IO_PENDING,
1696 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1697 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1698 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1699 pool_.get(), NetLogWithSource()));
1700
1701 handle.Reset();
1702 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1703 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1704
1705 // This will create a second ConnectJob, since the other ConnectJob was
1706 // previously assigned to a request.
1707 TestCompletionCallback callback2;
1708 EXPECT_EQ(
1709 ERR_IO_PENDING,
1710 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1711 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1712 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
1713 pool_.get(), NetLogWithSource()));
1714
1715 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1716 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
1717
1718 EXPECT_THAT(callback2.WaitForResult(), IsOk());
1719 EXPECT_FALSE(callback.have_result());
1720 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1721 // One ConnectJob completed, and its socket is now assigned to |handle|.
1722 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1723 // The other ConnectJob should have either completed, or still be connecting.
1724 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1725 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1726
1727 handle.Reset();
1728 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
1729 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) +
1730 pool_->IdleSocketCountInGroup(TestGroupId("a")));
1731 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
1732 }
1733
TEST_F(ClientSocketPoolBaseTest,CancelRequest)1734 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1735 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1736
1737 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1738 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
1739 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1740 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
1741 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
1742 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
1743 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
1744
1745 // Cancel a request.
1746 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1747 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1748 (*requests())[index_to_cancel]->handle()->Reset();
1749
1750 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1751
1752 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1753 client_socket_factory_.allocation_count());
1754 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1755 completion_count());
1756
1757 EXPECT_EQ(1, GetOrderOfRequest(1));
1758 EXPECT_EQ(2, GetOrderOfRequest(2));
1759 EXPECT_EQ(5, GetOrderOfRequest(3));
1760 EXPECT_EQ(3, GetOrderOfRequest(4));
1761 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1762 GetOrderOfRequest(5)); // Canceled request.
1763 EXPECT_EQ(4, GetOrderOfRequest(6));
1764 EXPECT_EQ(6, GetOrderOfRequest(7));
1765
1766 // Make sure we test order of all requests made.
1767 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1768 }
1769
1770 // Function to be used as a callback on socket request completion. It first
1771 // disconnects the successfully connected socket from the first request, and
1772 // then reuses the ClientSocketHandle to request another socket.
1773 //
1774 // |nested_callback| is called with the result of the second socket request.
RequestSocketOnComplete(ClientSocketHandle * handle,TransportClientSocketPool * pool,TestConnectJobFactory * test_connect_job_factory,TestConnectJob::JobType next_job_type,TestCompletionCallback * nested_callback,int first_request_result)1775 void RequestSocketOnComplete(ClientSocketHandle* handle,
1776 TransportClientSocketPool* pool,
1777 TestConnectJobFactory* test_connect_job_factory,
1778 TestConnectJob::JobType next_job_type,
1779 TestCompletionCallback* nested_callback,
1780 int first_request_result) {
1781 EXPECT_THAT(first_request_result, IsOk());
1782
1783 test_connect_job_factory->set_job_type(next_job_type);
1784
1785 // Don't allow reuse of the socket. Disconnect it and then release it.
1786 if (handle->socket()) {
1787 handle->socket()->Disconnect();
1788 }
1789 handle->Reset();
1790
1791 TestCompletionCallback callback;
1792 int rv = handle->Init(
1793 TestGroupId("a"),
1794 ClientSocketPool::SocketParams::CreateForHttpForTesting(), std::nullopt,
1795 LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1796 nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
1797 NetLogWithSource());
1798 if (rv != ERR_IO_PENDING) {
1799 DCHECK_EQ(TestConnectJob::kMockJob, next_job_type);
1800 nested_callback->callback().Run(rv);
1801 } else {
1802 DCHECK_EQ(TestConnectJob::kMockPendingJob, next_job_type);
1803 }
1804 }
1805
1806 // Tests the case where a second socket is requested in a completion callback,
1807 // and the second socket connects asynchronously. Reuses the same
1808 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobTwice)1809 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1810 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1811
1812 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1813 ClientSocketHandle handle;
1814 TestCompletionCallback second_result_callback;
1815 int rv = handle.Init(
1816 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1817 ClientSocketPool::RespectLimits::ENABLED,
1818 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1819 connect_job_factory_, TestConnectJob::kMockPendingJob,
1820 &second_result_callback),
1821 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1822 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1823
1824 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1825 }
1826
1827 // Tests the case where a second socket is requested in a completion callback,
1828 // and the second socket connects synchronously. Reuses the same
1829 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(ClientSocketPoolBaseTest,RequestPendingJobThenSynchronous)1830 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1831 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1832
1833 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1834 ClientSocketHandle handle;
1835 TestCompletionCallback second_result_callback;
1836 int rv = handle.Init(
1837 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1838 ClientSocketPool::RespectLimits::ENABLED,
1839 base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
1840 connect_job_factory_, TestConnectJob::kMockPendingJob,
1841 &second_result_callback),
1842 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1843 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1844
1845 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
1846 }
1847
1848 // Make sure that pending requests get serviced after active requests get
1849 // cancelled.
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestWithPendingRequests)1850 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1851 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1852
1853 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1854
1855 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1856 IsError(ERR_IO_PENDING));
1857 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1858 IsError(ERR_IO_PENDING));
1859 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1860 IsError(ERR_IO_PENDING));
1861 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1862 IsError(ERR_IO_PENDING));
1863 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1864 IsError(ERR_IO_PENDING));
1865 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1866 IsError(ERR_IO_PENDING));
1867 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1868 IsError(ERR_IO_PENDING));
1869
1870 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1871 // Let's cancel them.
1872 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1873 ASSERT_FALSE(request(i)->handle()->is_initialized());
1874 request(i)->handle()->Reset();
1875 }
1876
1877 // Let's wait for the rest to complete now.
1878 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1879 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
1880 request(i)->handle()->Reset();
1881 }
1882
1883 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup, completion_count());
1884 }
1885
1886 // Make sure that pending requests get serviced after active requests fail.
TEST_F(ClientSocketPoolBaseTest,FailingActiveRequestWithPendingRequests)1887 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1888 const size_t kMaxSockets = 5;
1889 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1890
1891 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1892
1893 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1894 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
1895
1896 // Queue up all the requests
1897 for (size_t i = 0; i < kNumberOfRequests; ++i) {
1898 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1899 IsError(ERR_IO_PENDING));
1900 }
1901
1902 for (size_t i = 0; i < kNumberOfRequests; ++i) {
1903 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1904 }
1905 }
1906
1907 // Make sure that pending requests that complete synchronously get serviced
1908 // after active requests fail. See https://crbug.com/723748
TEST_F(ClientSocketPoolBaseTest,HandleMultipleSyncFailuresAfterAsyncFailure)1909 TEST_F(ClientSocketPoolBaseTest, HandleMultipleSyncFailuresAfterAsyncFailure) {
1910 const size_t kNumberOfRequests = 10;
1911 const size_t kMaxSockets = 1;
1912 CreatePool(kMaxSockets, kMaxSockets);
1913
1914 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1915
1916 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1917 IsError(ERR_IO_PENDING));
1918
1919 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1920
1921 // Queue up all the other requests
1922 for (size_t i = 1; i < kNumberOfRequests; ++i) {
1923 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
1924 IsError(ERR_IO_PENDING));
1925 }
1926
1927 // Make sure all requests fail, instead of hanging.
1928 for (size_t i = 0; i < kNumberOfRequests; ++i) {
1929 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
1930 }
1931 }
1932
TEST_F(ClientSocketPoolBaseTest,CancelActiveRequestThenRequestSocket)1933 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1934 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1935
1936 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1937
1938 ClientSocketHandle handle;
1939 TestCompletionCallback callback;
1940 int rv = handle.Init(
1941 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
1942 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1943 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
1944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1945
1946 // Cancel the active request.
1947 handle.Reset();
1948
1949 rv = handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
1950 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1951 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1952 pool_.get(), NetLogWithSource());
1953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1954 EXPECT_THAT(callback.WaitForResult(), IsOk());
1955
1956 EXPECT_FALSE(handle.is_reused());
1957 TestLoadTimingInfoConnectedNotReused(handle);
1958 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1959 }
1960
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsForced)1961 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) {
1962 const char kReason[] = "Really nifty reason";
1963
1964 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1965 ClientSocketHandle handle;
1966 TestCompletionCallback callback;
1967 int rv =
1968 handle.Init(TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
1969 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1970 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
1971 NetLogWithSource::Make(NetLogSourceType::NONE));
1972 EXPECT_THAT(rv, IsOk());
1973 ASSERT_TRUE(handle.socket());
1974 NetLogSource source = handle.socket()->NetLog().source();
1975 handle.Reset();
1976 EXPECT_EQ(1, pool_->IdleSocketCount());
1977 pool_->CloseIdleSockets(kReason);
1978 ExpectSocketClosedWithReason(source, kReason);
1979 }
1980
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsInGroupForced)1981 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) {
1982 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1983 TestCompletionCallback callback;
1984 NetLogWithSource net_log_with_source =
1985 NetLogWithSource::Make(NetLogSourceType::NONE);
1986 ClientSocketHandle handle1;
1987 int rv = handle1.Init(
1988 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
1989 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1990 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
1991 EXPECT_THAT(rv, IsOk());
1992 ClientSocketHandle handle2;
1993 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
1994 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
1995 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1996 pool_.get(), net_log_with_source);
1997 ClientSocketHandle handle3;
1998 rv = handle3.Init(TestGroupId("b"), params_, std::nullopt, LOWEST,
1999 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2000 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2001 pool_.get(), net_log_with_source);
2002 EXPECT_THAT(rv, IsOk());
2003 handle1.Reset();
2004 handle2.Reset();
2005 handle3.Reset();
2006 EXPECT_EQ(3, pool_->IdleSocketCount());
2007 pool_->CloseIdleSocketsInGroup(TestGroupId("a"), "Very good reason");
2008 EXPECT_EQ(1, pool_->IdleSocketCount());
2009 }
2010
TEST_F(ClientSocketPoolBaseTest,CleanUpUnusableIdleSockets)2011 TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) {
2012 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2013 ClientSocketHandle handle;
2014 TestCompletionCallback callback;
2015 NetLogWithSource net_log_with_source =
2016 NetLogWithSource::Make(NetLogSourceType::NONE);
2017 int rv = handle.Init(
2018 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2019 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2020 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2021 EXPECT_THAT(rv, IsOk());
2022 StreamSocket* socket = handle.socket();
2023 ASSERT_TRUE(socket);
2024 handle.Reset();
2025 EXPECT_EQ(1, pool_->IdleSocketCount());
2026
2027 // Disconnect socket now to make the socket unusable.
2028 NetLogSource source = socket->NetLog().source();
2029 socket->Disconnect();
2030 ClientSocketHandle handle2;
2031 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2032 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2033 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2034 pool_.get(), net_log_with_source);
2035 EXPECT_THAT(rv, IsOk());
2036 EXPECT_FALSE(handle2.is_reused());
2037
2038 // This is admittedly not an accurate error in this case, but normally code
2039 // doesn't secretly keep a raw pointers to sockets returned to the socket pool
2040 // and close them out of band, so discovering an idle socket was closed when
2041 // trying to reuse it normally means it was closed by the remote side.
2042 ExpectSocketClosedWithReason(
2043 source, TransportClientSocketPool::kRemoteSideClosedConnection);
2044 }
2045
2046 // Regression test for http://crbug.com/17985.
TEST_F(ClientSocketPoolBaseTest,GroupWithPendingRequestsIsNotEmpty)2047 TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
2048 const int kMaxSockets = 3;
2049 const int kMaxSocketsPerGroup = 2;
2050 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
2051
2052 const RequestPriority kHighPriority = HIGHEST;
2053
2054 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2055 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2056
2057 // This is going to be a pending request in an otherwise empty group.
2058 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2059 IsError(ERR_IO_PENDING));
2060
2061 // Reach the maximum socket limit.
2062 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2063
2064 // Create a stalled group with high priorities.
2065 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2066 IsError(ERR_IO_PENDING));
2067 EXPECT_THAT(StartRequest(TestGroupId("c"), kHighPriority),
2068 IsError(ERR_IO_PENDING));
2069
2070 // Release the first two sockets from TestGroupId("a"). Because this is a
2071 // keepalive, the first release will unblock the pending request for
2072 // TestGroupId("a"). The second release will unblock a request for "c",
2073 // because it is the next high priority socket.
2074 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2075 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
2076
2077 // Closing idle sockets should not get us into trouble, but in the bug
2078 // we were hitting a CHECK here.
2079 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2080 pool_->CloseIdleSockets("Very good reason");
2081
2082 // Run the released socket wakeups.
2083 base::RunLoop().RunUntilIdle();
2084 }
2085
TEST_F(ClientSocketPoolBaseTest,BasicAsynchronous)2086 TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
2087 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2088
2089 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2090 ClientSocketHandle handle;
2091 TestCompletionCallback callback;
2092 NetLogWithSource net_log_with_source =
2093 NetLogWithSource::Make(NetLogSourceType::NONE);
2094 int rv = handle.Init(
2095 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2096 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2097 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2099 EXPECT_EQ(LOAD_STATE_CONNECTING,
2100 pool_->GetLoadState(TestGroupId("a"), &handle));
2101 TestLoadTimingInfoNotConnected(handle);
2102
2103 EXPECT_THAT(callback.WaitForResult(), IsOk());
2104 EXPECT_TRUE(handle.is_initialized());
2105 EXPECT_TRUE(handle.socket());
2106 TestLoadTimingInfoConnectedNotReused(handle);
2107
2108 handle.Reset();
2109 TestLoadTimingInfoNotConnected(handle);
2110
2111 auto entries =
2112 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2113
2114 EXPECT_EQ(5u, entries.size());
2115 EXPECT_TRUE(LogContainsEvent(
2116 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2117 NetLogEventPhase::NONE));
2118 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2119 EXPECT_TRUE(LogContainsEvent(
2120 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2121 NetLogEventPhase::NONE));
2122 EXPECT_TRUE(LogContainsEvent(entries, 3,
2123 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET,
2124 NetLogEventPhase::NONE));
2125 EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::SOCKET_POOL));
2126 }
2127
TEST_F(ClientSocketPoolBaseTest,InitConnectionAsynchronousFailure)2128 TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
2129 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2130
2131 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2132 ClientSocketHandle handle;
2133 TestCompletionCallback callback;
2134 NetLogWithSource net_log_with_source =
2135 NetLogWithSource::Make(NetLogSourceType::NONE);
2136 // Set the additional error state members to ensure that they get cleared.
2137 handle.set_is_ssl_error(true);
2138 handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
2139 EXPECT_EQ(
2140 ERR_IO_PENDING,
2141 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2142 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2143 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2144 pool_.get(), net_log_with_source));
2145 EXPECT_EQ(LOAD_STATE_CONNECTING,
2146 pool_->GetLoadState(TestGroupId("a"), &handle));
2147 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2148 EXPECT_FALSE(handle.is_ssl_error());
2149 EXPECT_FALSE(handle.ssl_cert_request_info());
2150
2151 auto entries =
2152 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2153
2154 EXPECT_EQ(4u, entries.size());
2155 EXPECT_TRUE(LogContainsEvent(
2156 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2157 NetLogEventPhase::NONE));
2158 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2159 EXPECT_TRUE(LogContainsEvent(
2160 entries, 2, NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
2161 NetLogEventPhase::NONE));
2162 EXPECT_TRUE(LogContainsEndEvent(entries, 3, NetLogEventType::SOCKET_POOL));
2163 }
2164
2165 // Check that an async ConnectJob failure does not result in creation of a new
2166 // ConnectJob when there's another pending request also waiting on its own
2167 // ConnectJob. See http://crbug.com/463960.
TEST_F(ClientSocketPoolBaseTest,AsyncFailureWithPendingRequestWithJob)2168 TEST_F(ClientSocketPoolBaseTest, AsyncFailureWithPendingRequestWithJob) {
2169 CreatePool(2, 2);
2170 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2171
2172 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2173 IsError(ERR_IO_PENDING));
2174 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2175 IsError(ERR_IO_PENDING));
2176
2177 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2178 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2179
2180 EXPECT_EQ(2, client_socket_factory_.allocation_count());
2181 }
2182
TEST_F(ClientSocketPoolBaseTest,TwoRequestsCancelOne)2183 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
2184 // TODO(eroman): Add back the log expectations! Removed them because the
2185 // ordering is difficult, and some may fire during destructor.
2186 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2187
2188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2189 ClientSocketHandle handle;
2190 TestCompletionCallback callback;
2191 ClientSocketHandle handle2;
2192 TestCompletionCallback callback2;
2193
2194 EXPECT_EQ(
2195 ERR_IO_PENDING,
2196 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2197 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2198 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2199 pool_.get(), NetLogWithSource()));
2200 RecordingNetLogObserver log2;
2201 EXPECT_EQ(
2202 ERR_IO_PENDING,
2203 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2204 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2205 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2206 pool_.get(), NetLogWithSource()));
2207
2208 handle.Reset();
2209
2210 // At this point, request 2 is just waiting for the connect job to finish.
2211
2212 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2213 handle2.Reset();
2214
2215 // Now request 2 has actually finished.
2216 // TODO(eroman): Add back log expectations.
2217 }
2218
TEST_F(ClientSocketPoolBaseTest,CancelRequestLimitsJobs)2219 TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
2220 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2221
2222 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2223
2224 EXPECT_THAT(StartRequest(TestGroupId("a"), LOWEST), IsError(ERR_IO_PENDING));
2225 EXPECT_THAT(StartRequest(TestGroupId("a"), LOW), IsError(ERR_IO_PENDING));
2226 EXPECT_THAT(StartRequest(TestGroupId("a"), MEDIUM), IsError(ERR_IO_PENDING));
2227 EXPECT_THAT(StartRequest(TestGroupId("a"), HIGHEST), IsError(ERR_IO_PENDING));
2228
2229 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2230 static_cast<int>(
2231 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2232 (*requests())[2]->handle()->Reset();
2233 (*requests())[3]->handle()->Reset();
2234 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2235 static_cast<int>(
2236 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2237
2238 (*requests())[1]->handle()->Reset();
2239 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2240 static_cast<int>(
2241 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2242
2243 (*requests())[0]->handle()->Reset();
2244 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
2245 static_cast<int>(
2246 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
2247 }
2248
2249 // When requests and ConnectJobs are not coupled, the request will get serviced
2250 // by whatever comes first.
TEST_F(ClientSocketPoolBaseTest,ReleaseSockets)2251 TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
2252 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2253
2254 // Start job 1 (async OK)
2255 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2256
2257 std::vector<raw_ptr<TestSocketRequest, VectorExperimental>> request_order;
2258 size_t completion_count; // unused
2259 TestSocketRequest req1(&request_order, &completion_count);
2260 int rv = req1.handle()->Init(
2261 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2262 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2263 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2265 EXPECT_THAT(req1.WaitForResult(), IsOk());
2266
2267 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
2268 // without a job.
2269 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2270
2271 TestSocketRequest req2(&request_order, &completion_count);
2272 rv = req2.handle()->Init(
2273 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2274 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2275 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2277 TestSocketRequest req3(&request_order, &completion_count);
2278 rv = req3.handle()->Init(
2279 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2280 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2281 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2283
2284 // Both Requests 2 and 3 are pending. We release socket 1 which should
2285 // service request 2. Request 3 should still be waiting.
2286 req1.handle()->Reset();
2287 // Run the released socket wakeups.
2288 base::RunLoop().RunUntilIdle();
2289 ASSERT_TRUE(req2.handle()->socket());
2290 EXPECT_THAT(req2.WaitForResult(), IsOk());
2291 EXPECT_FALSE(req3.handle()->socket());
2292
2293 // Signal job 2, which should service request 3.
2294
2295 client_socket_factory_.SignalJobs();
2296 EXPECT_THAT(req3.WaitForResult(), IsOk());
2297
2298 ASSERT_EQ(3u, request_order.size());
2299 EXPECT_EQ(&req1, request_order[0]);
2300 EXPECT_EQ(&req2, request_order[1]);
2301 EXPECT_EQ(&req3, request_order[2]);
2302 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2303 }
2304
2305 // The requests are not coupled to the jobs. So, the requests should finish in
2306 // their priority / insertion order.
TEST_F(ClientSocketPoolBaseTest,PendingJobCompletionOrder)2307 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
2308 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2309 // First two jobs are async.
2310 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2311
2312 std::vector<raw_ptr<TestSocketRequest, VectorExperimental>> request_order;
2313 size_t completion_count; // unused
2314 TestSocketRequest req1(&request_order, &completion_count);
2315 int rv = req1.handle()->Init(
2316 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2317 ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
2318 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2320
2321 TestSocketRequest req2(&request_order, &completion_count);
2322 rv = req2.handle()->Init(
2323 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2324 ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
2325 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2327
2328 // The pending job is sync.
2329 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2330
2331 TestSocketRequest req3(&request_order, &completion_count);
2332 rv = req3.handle()->Init(
2333 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2334 ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
2335 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2337
2338 EXPECT_THAT(req1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2339 EXPECT_THAT(req2.WaitForResult(), IsOk());
2340 EXPECT_THAT(req3.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2341
2342 ASSERT_EQ(3u, request_order.size());
2343 EXPECT_EQ(&req1, request_order[0]);
2344 EXPECT_EQ(&req2, request_order[1]);
2345 EXPECT_EQ(&req3, request_order[2]);
2346 }
2347
2348 // Test GetLoadState in the case there's only one socket request.
TEST_F(ClientSocketPoolBaseTest,LoadStateOneRequest)2349 TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) {
2350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2351 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2352
2353 ClientSocketHandle handle;
2354 TestCompletionCallback callback;
2355 int rv = handle.Init(
2356 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2357 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2358 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2360 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2361
2362 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2363 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2364
2365 // No point in completing the connection, since ClientSocketHandles only
2366 // expect the LoadState to be checked while connecting.
2367 }
2368
2369 // Test GetLoadState in the case there are two socket requests.
TEST_F(ClientSocketPoolBaseTest,LoadStateTwoRequests)2370 TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) {
2371 CreatePool(2, 2);
2372 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2373
2374 ClientSocketHandle handle;
2375 TestCompletionCallback callback;
2376 int rv = handle.Init(
2377 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2378 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2379 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2381 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
2382
2383 ClientSocketHandle handle2;
2384 TestCompletionCallback callback2;
2385 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2386 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2387 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2388 pool_.get(), NetLogWithSource());
2389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2390 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_RESOLVING_HOST);
2391
2392 // Each handle should reflect the state of its own job.
2393 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle.GetLoadState());
2394 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2395
2396 // Update the state of the first job.
2397 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
2398
2399 // Only the state of the first request should have changed.
2400 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2401 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, handle2.GetLoadState());
2402
2403 // Update the state of the second job.
2404 client_socket_factory_.SetJobLoadState(1, LOAD_STATE_SSL_HANDSHAKE);
2405
2406 // Only the state of the second request should have changed.
2407 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2408 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2409
2410 // Second job connects and the first request gets the socket. The
2411 // second handle switches to the state of the remaining ConnectJob.
2412 client_socket_factory_.SignalJob(1);
2413 EXPECT_THAT(callback.WaitForResult(), IsOk());
2414 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2415 }
2416
2417 // Test GetLoadState in the case the per-group limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStateGroupLimit)2418 TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) {
2419 CreatePool(2, 1);
2420 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2421
2422 ClientSocketHandle handle;
2423 TestCompletionCallback callback;
2424 int rv = handle.Init(
2425 TestGroupId("a"), params_, std::nullopt, MEDIUM, SocketTag(),
2426 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2427 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2429 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2430
2431 // Request another socket from the same pool, buth with a higher priority.
2432 // The first request should now be stalled at the socket group limit.
2433 ClientSocketHandle handle2;
2434 TestCompletionCallback callback2;
2435 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
2436 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2437 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2438 pool_.get(), NetLogWithSource());
2439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2440 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2441 EXPECT_EQ(LOAD_STATE_CONNECTING, handle2.GetLoadState());
2442
2443 // The first handle should remain stalled as the other socket goes through
2444 // the connect process.
2445
2446 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2447 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2448 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle2.GetLoadState());
2449
2450 client_socket_factory_.SignalJob(0);
2451 EXPECT_THAT(callback2.WaitForResult(), IsOk());
2452 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, handle.GetLoadState());
2453
2454 // Closing the second socket should cause the stalled handle to finally get a
2455 // ConnectJob.
2456 handle2.socket()->Disconnect();
2457 handle2.Reset();
2458 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2459 }
2460
2461 // Test GetLoadState in the case the per-pool limit is reached.
TEST_F(ClientSocketPoolBaseTest,LoadStatePoolLimit)2462 TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) {
2463 CreatePool(2, 2);
2464 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2465
2466 ClientSocketHandle handle;
2467 TestCompletionCallback callback;
2468 int rv = handle.Init(
2469 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2470 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2471 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2473
2474 // Request for socket from another pool.
2475 ClientSocketHandle handle2;
2476 TestCompletionCallback callback2;
2477 rv = handle2.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
2478 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2479 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2480 pool_.get(), NetLogWithSource());
2481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2482
2483 // Request another socket from the first pool. Request should stall at the
2484 // socket pool limit.
2485 ClientSocketHandle handle3;
2486 TestCompletionCallback callback3;
2487 rv = handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2488 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2489 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2490 pool_.get(), NetLogWithSource());
2491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2492
2493 // The third handle should remain stalled as the other sockets in its group
2494 // goes through the connect process.
2495
2496 EXPECT_EQ(LOAD_STATE_CONNECTING, handle.GetLoadState());
2497 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2498
2499 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
2500 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, handle.GetLoadState());
2501 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2502
2503 client_socket_factory_.SignalJob(0);
2504 EXPECT_THAT(callback.WaitForResult(), IsOk());
2505 EXPECT_EQ(LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL, handle3.GetLoadState());
2506
2507 // Closing a socket should allow the stalled handle to finally get a new
2508 // ConnectJob.
2509 handle.socket()->Disconnect();
2510 handle.Reset();
2511 EXPECT_EQ(LOAD_STATE_CONNECTING, handle3.GetLoadState());
2512 }
2513
TEST_F(ClientSocketPoolBaseTest,CertError)2514 TEST_F(ClientSocketPoolBaseTest, CertError) {
2515 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2516 connect_job_factory_->set_job_type(TestConnectJob::kMockCertErrorJob);
2517
2518 ClientSocketHandle handle;
2519 TestCompletionCallback callback;
2520 EXPECT_EQ(
2521 ERR_CERT_COMMON_NAME_INVALID,
2522 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2523 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2524 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2525 pool_.get(), NetLogWithSource()));
2526 EXPECT_TRUE(handle.is_initialized());
2527 EXPECT_TRUE(handle.socket());
2528 }
2529
TEST_F(ClientSocketPoolBaseTest,AsyncCertError)2530 TEST_F(ClientSocketPoolBaseTest, AsyncCertError) {
2531 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2532
2533 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingCertErrorJob);
2534 ClientSocketHandle handle;
2535 TestCompletionCallback callback;
2536 EXPECT_EQ(
2537 ERR_IO_PENDING,
2538 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2539 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2540 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2541 pool_.get(), NetLogWithSource()));
2542 EXPECT_EQ(LOAD_STATE_CONNECTING,
2543 pool_->GetLoadState(TestGroupId("a"), &handle));
2544 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID));
2545 EXPECT_TRUE(handle.is_initialized());
2546 EXPECT_TRUE(handle.socket());
2547 }
2548
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateSynchronous)2549 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
2550 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2551 connect_job_factory_->set_job_type(
2552 TestConnectJob::kMockAdditionalErrorStateJob);
2553
2554 ClientSocketHandle handle;
2555 TestCompletionCallback callback;
2556 EXPECT_EQ(
2557 ERR_CONNECTION_FAILED,
2558 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2559 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2560 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2561 pool_.get(), NetLogWithSource()));
2562 EXPECT_FALSE(handle.is_initialized());
2563 EXPECT_FALSE(handle.socket());
2564 EXPECT_TRUE(handle.is_ssl_error());
2565 EXPECT_TRUE(handle.ssl_cert_request_info());
2566 }
2567
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorStateAsynchronous)2568 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
2569 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2570
2571 connect_job_factory_->set_job_type(
2572 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2573 ClientSocketHandle handle;
2574 TestCompletionCallback callback;
2575 EXPECT_EQ(
2576 ERR_IO_PENDING,
2577 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2578 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2579 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2580 pool_.get(), NetLogWithSource()));
2581 EXPECT_EQ(LOAD_STATE_CONNECTING,
2582 pool_->GetLoadState(TestGroupId("a"), &handle));
2583 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2584 EXPECT_FALSE(handle.is_initialized());
2585 EXPECT_FALSE(handle.socket());
2586 EXPECT_TRUE(handle.is_ssl_error());
2587 EXPECT_TRUE(handle.ssl_cert_request_info());
2588 }
2589
2590 // Make sure we can reuse sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsReuse)2591 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) {
2592 CreatePoolWithIdleTimeouts(
2593 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2594 base::TimeDelta(), // Time out unused sockets immediately.
2595 base::Days(1)); // Don't time out used sockets.
2596
2597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2598
2599 ClientSocketHandle handle;
2600 TestCompletionCallback callback;
2601 int rv = handle.Init(
2602 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2603 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2604 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2605 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2606 EXPECT_EQ(LOAD_STATE_CONNECTING,
2607 pool_->GetLoadState(TestGroupId("a"), &handle));
2608 ASSERT_THAT(callback.WaitForResult(), IsOk());
2609
2610 // Use and release the socket.
2611 EXPECT_EQ(1, handle.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2612 TRAFFIC_ANNOTATION_FOR_TESTS));
2613 TestLoadTimingInfoConnectedNotReused(handle);
2614 handle.Reset();
2615
2616 // Should now have one idle socket.
2617 ASSERT_EQ(1, pool_->IdleSocketCount());
2618
2619 // Request a new socket. This should reuse the old socket and complete
2620 // synchronously.
2621 NetLogWithSource net_log_with_source =
2622 NetLogWithSource::Make(NetLogSourceType::NONE);
2623 rv = handle.Init(
2624 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2625 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2626 ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
2627 ASSERT_THAT(rv, IsOk());
2628 EXPECT_TRUE(handle.is_reused());
2629 TestLoadTimingInfoConnectedReused(handle);
2630
2631 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2632 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2633 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2634
2635 auto entries =
2636 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2637 EXPECT_TRUE(LogContainsEvent(
2638 entries, 0, NetLogEventType::TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
2639 NetLogEventPhase::NONE));
2640 EXPECT_TRUE(LogContainsBeginEvent(entries, 1, NetLogEventType::SOCKET_POOL));
2641 EXPECT_TRUE(LogContainsEntryWithType(
2642 entries, 2, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2643 }
2644
2645 // Make sure we cleanup old unused sockets.
TEST_F(ClientSocketPoolBaseTest,CleanupTimedOutIdleSocketsNoReuse)2646 TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) {
2647 CreatePoolWithIdleTimeouts(
2648 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2649 base::TimeDelta(), // Time out unused sockets immediately
2650 base::TimeDelta()); // Time out used sockets immediately
2651
2652 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2653
2654 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2655
2656 ClientSocketHandle handle;
2657 TestCompletionCallback callback;
2658 int rv = handle.Init(
2659 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2660 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2661 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2662 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2663 EXPECT_EQ(LOAD_STATE_CONNECTING,
2664 pool_->GetLoadState(TestGroupId("a"), &handle));
2665
2666 ClientSocketHandle handle2;
2667 TestCompletionCallback callback2;
2668 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2669 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2670 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2671 pool_.get(), NetLogWithSource());
2672 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2673 EXPECT_EQ(LOAD_STATE_CONNECTING,
2674 pool_->GetLoadState(TestGroupId("a"), &handle2));
2675
2676 // Cancel one of the requests. Wait for the other, which will get the first
2677 // job. Release the socket. Run the loop again to make sure the second
2678 // socket is sitting idle and the first one is released (since ReleaseSocket()
2679 // just posts a DoReleaseSocket() task).
2680
2681 handle.Reset();
2682 ASSERT_THAT(callback2.WaitForResult(), IsOk());
2683 // Get the NetLogSource for the socket, so the time out reason can be checked
2684 // at the end of the test.
2685 NetLogSource net_log_source2 = handle2.socket()->NetLog().source();
2686 // Use the socket.
2687 EXPECT_EQ(1, handle2.socket()->Write(nullptr, 1, CompletionOnceCallback(),
2688 TRAFFIC_ANNOTATION_FOR_TESTS));
2689 handle2.Reset();
2690
2691 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2692 // actually become pending until 2ms after they have been created. In order
2693 // to flush all tasks, we need to wait so that we know there are no
2694 // soon-to-be-pending tasks waiting.
2695 FastForwardBy(base::Milliseconds(10));
2696
2697 // Both sockets should now be idle.
2698 ASSERT_EQ(2, pool_->IdleSocketCount());
2699
2700 // Request a new socket. This should cleanup the unused and timed out ones.
2701 // A new socket will be created rather than reusing the idle one.
2702 NetLogWithSource net_log_with_source =
2703 NetLogWithSource::Make(NetLogSourceType::NONE);
2704 TestCompletionCallback callback3;
2705 rv = handle.Init(TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2706 ClientSocketPool::RespectLimits::ENABLED,
2707 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2708 pool_.get(), net_log_with_source);
2709 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
2710 ASSERT_THAT(callback3.WaitForResult(), IsOk());
2711 EXPECT_FALSE(handle.is_reused());
2712
2713 // Make sure the idle socket is closed.
2714 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
2715 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
2716 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
2717
2718 auto entries =
2719 net_log_observer_.GetEntriesForSource(net_log_with_source.source());
2720 EXPECT_FALSE(LogContainsEntryWithType(
2721 entries, 1, NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2722 ExpectSocketClosedWithReason(
2723 net_log_source2, TransportClientSocketPool::kIdleTimeLimitExpired);
2724 }
2725
2726 // Make sure that we process all pending requests even when we're stalling
2727 // because of multiple releasing disconnected sockets.
TEST_F(ClientSocketPoolBaseTest,MultipleReleasingDisconnectedSockets)2728 TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2729 CreatePoolWithIdleTimeouts(
2730 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2731 base::TimeDelta(), // Time out unused sockets immediately.
2732 base::Days(1)); // Don't time out used sockets.
2733
2734 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2735
2736 // Startup 4 connect jobs. Two of them will be pending.
2737
2738 ClientSocketHandle handle;
2739 TestCompletionCallback callback;
2740 int rv = handle.Init(
2741 TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
2742 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
2743 ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
2744 EXPECT_THAT(rv, IsOk());
2745
2746 ClientSocketHandle handle2;
2747 TestCompletionCallback callback2;
2748 rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2749 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2750 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
2751 pool_.get(), NetLogWithSource());
2752 EXPECT_THAT(rv, IsOk());
2753
2754 ClientSocketHandle handle3;
2755 TestCompletionCallback callback3;
2756 rv = handle3.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2757 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2758 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
2759 pool_.get(), NetLogWithSource());
2760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2761
2762 ClientSocketHandle handle4;
2763 TestCompletionCallback callback4;
2764 rv = handle4.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2765 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2766 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
2767 pool_.get(), NetLogWithSource());
2768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2769
2770 // Release two disconnected sockets.
2771
2772 handle.socket()->Disconnect();
2773 handle.Reset();
2774 handle2.socket()->Disconnect();
2775 handle2.Reset();
2776
2777 EXPECT_THAT(callback3.WaitForResult(), IsOk());
2778 EXPECT_FALSE(handle3.is_reused());
2779 EXPECT_THAT(callback4.WaitForResult(), IsOk());
2780 EXPECT_FALSE(handle4.is_reused());
2781 }
2782
2783 // Regression test for http://crbug.com/42267.
2784 // When DoReleaseSocket() is processed for one socket, it is blocked because the
2785 // other stalled groups all have releasing sockets, so no progress can be made.
TEST_F(ClientSocketPoolBaseTest,SocketLimitReleasingSockets)2786 TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2787 CreatePoolWithIdleTimeouts(
2788 4 /* socket limit */, 4 /* socket limit per group */,
2789 base::TimeDelta(), // Time out unused sockets immediately.
2790 base::Days(1)); // Don't time out used sockets.
2791
2792 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2793
2794 // Max out the socket limit with 2 per group.
2795
2796 ClientSocketHandle handle_a[4];
2797 TestCompletionCallback callback_a[4];
2798 ClientSocketHandle handle_b[4];
2799 TestCompletionCallback callback_b[4];
2800
2801 for (int i = 0; i < 2; ++i) {
2802 EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, std::nullopt,
2803 LOWEST, SocketTag(),
2804 ClientSocketPool::RespectLimits::ENABLED,
2805 callback_a[i].callback(),
2806 ClientSocketPool::ProxyAuthCallback(),
2807 pool_.get(), NetLogWithSource()));
2808 EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, std::nullopt,
2809 LOWEST, SocketTag(),
2810 ClientSocketPool::RespectLimits::ENABLED,
2811 callback_b[i].callback(),
2812 ClientSocketPool::ProxyAuthCallback(),
2813 pool_.get(), NetLogWithSource()));
2814 }
2815
2816 // Make 4 pending requests, 2 per group.
2817
2818 for (int i = 2; i < 4; ++i) {
2819 EXPECT_EQ(
2820 ERR_IO_PENDING,
2821 handle_a[i].Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
2822 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2823 callback_a[i].callback(),
2824 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2825 NetLogWithSource()));
2826 EXPECT_EQ(
2827 ERR_IO_PENDING,
2828 handle_b[i].Init(TestGroupId("b"), params_, std::nullopt, LOWEST,
2829 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2830 callback_b[i].callback(),
2831 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
2832 NetLogWithSource()));
2833 }
2834
2835 // Release b's socket first. The order is important, because in
2836 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2837 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2838 // first, which has a releasing socket, so it refuses to start up another
2839 // ConnectJob. So, we used to infinite loop on this.
2840 handle_b[0].socket()->Disconnect();
2841 handle_b[0].Reset();
2842 handle_a[0].socket()->Disconnect();
2843 handle_a[0].Reset();
2844
2845 // Used to get stuck here.
2846 base::RunLoop().RunUntilIdle();
2847
2848 handle_b[1].socket()->Disconnect();
2849 handle_b[1].Reset();
2850 handle_a[1].socket()->Disconnect();
2851 handle_a[1].Reset();
2852
2853 for (int i = 2; i < 4; ++i) {
2854 EXPECT_THAT(callback_b[i].WaitForResult(), IsOk());
2855 EXPECT_THAT(callback_a[i].WaitForResult(), IsOk());
2856 }
2857 }
2858
TEST_F(ClientSocketPoolBaseTest,ReleasingDisconnectedSocketsMaintainsPriorityOrder)2859 TEST_F(ClientSocketPoolBaseTest,
2860 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2861 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2862
2863 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2864
2865 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2866 IsError(ERR_IO_PENDING));
2867 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2868 IsError(ERR_IO_PENDING));
2869 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2870 IsError(ERR_IO_PENDING));
2871 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY),
2872 IsError(ERR_IO_PENDING));
2873
2874 EXPECT_THAT((*requests())[0]->WaitForResult(), IsOk());
2875 EXPECT_THAT((*requests())[1]->WaitForResult(), IsOk());
2876 EXPECT_EQ(2u, completion_count());
2877
2878 // Releases one connection.
2879 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2880 EXPECT_THAT((*requests())[2]->WaitForResult(), IsOk());
2881
2882 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2883 EXPECT_THAT((*requests())[3]->WaitForResult(), IsOk());
2884 EXPECT_EQ(4u, completion_count());
2885
2886 EXPECT_EQ(1, GetOrderOfRequest(1));
2887 EXPECT_EQ(2, GetOrderOfRequest(2));
2888 EXPECT_EQ(3, GetOrderOfRequest(3));
2889 EXPECT_EQ(4, GetOrderOfRequest(4));
2890
2891 // Make sure we test order of all requests made.
2892 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2893 }
2894
2895 class TestReleasingSocketRequest : public TestCompletionCallbackBase {
2896 public:
TestReleasingSocketRequest(TransportClientSocketPool * pool,int expected_result,bool reset_releasing_handle)2897 TestReleasingSocketRequest(TransportClientSocketPool* pool,
2898 int expected_result,
2899 bool reset_releasing_handle)
2900 : pool_(pool),
2901 expected_result_(expected_result),
2902 reset_releasing_handle_(reset_releasing_handle) {}
2903
2904 ~TestReleasingSocketRequest() override = default;
2905
handle()2906 ClientSocketHandle* handle() { return &handle_; }
2907
callback()2908 CompletionOnceCallback callback() {
2909 return base::BindOnce(&TestReleasingSocketRequest::OnComplete,
2910 base::Unretained(this));
2911 }
2912
2913 private:
OnComplete(int result)2914 void OnComplete(int result) {
2915 SetResult(result);
2916 if (reset_releasing_handle_) {
2917 handle_.Reset();
2918 }
2919
2920 EXPECT_EQ(
2921 expected_result_,
2922 handle2_.Init(
2923 TestGroupId("a"),
2924 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
2925 std::nullopt, DEFAULT_PRIORITY, SocketTag(),
2926 ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
2927 ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
2928 }
2929
2930 const raw_ptr<TransportClientSocketPool> pool_;
2931 int expected_result_;
2932 bool reset_releasing_handle_;
2933 ClientSocketHandle handle_;
2934 ClientSocketHandle handle2_;
2935 };
2936
TEST_F(ClientSocketPoolBaseTest,AdditionalErrorSocketsDontUseSlot)2937 TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2938 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2939
2940 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2941 EXPECT_THAT(StartRequest(TestGroupId("a"), DEFAULT_PRIORITY), IsOk());
2942 EXPECT_THAT(StartRequest(TestGroupId("b"), DEFAULT_PRIORITY), IsOk());
2943
2944 EXPECT_EQ(static_cast<int>(requests_size()),
2945 client_socket_factory_.allocation_count());
2946
2947 connect_job_factory_->set_job_type(
2948 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2949 TestReleasingSocketRequest req(pool_.get(), OK, false);
2950 EXPECT_EQ(ERR_IO_PENDING,
2951 req.handle()->Init(
2952 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2953 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2954 req.callback(), ClientSocketPool::ProxyAuthCallback(),
2955 pool_.get(), NetLogWithSource()));
2956 // The next job should complete synchronously
2957 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2958
2959 EXPECT_THAT(req.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
2960 EXPECT_FALSE(req.handle()->is_initialized());
2961 EXPECT_FALSE(req.handle()->socket());
2962 EXPECT_TRUE(req.handle()->is_ssl_error());
2963 EXPECT_TRUE(req.handle()->ssl_cert_request_info());
2964 }
2965
2966 // http://crbug.com/44724 regression test.
2967 // We start releasing the pool when we flush on network change. When that
2968 // happens, the only active references are in the ClientSocketHandles. When a
2969 // ConnectJob completes and calls back into the last ClientSocketHandle, that
2970 // callback can release the last reference and delete the pool. After the
2971 // callback finishes, we go back to the stack frame within the now-deleted pool.
2972 // Executing any code that refers to members of the now-deleted pool can cause
2973 // crashes.
TEST_F(ClientSocketPoolBaseTest,CallbackThatReleasesPool)2974 TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2976 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2977
2978 ClientSocketHandle handle;
2979 TestCompletionCallback callback;
2980 EXPECT_EQ(
2981 ERR_IO_PENDING,
2982 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
2983 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
2984 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
2985 pool_.get(), NetLogWithSource()));
2986
2987 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
2988
2989 // We'll call back into this now.
2990 callback.WaitForResult();
2991 }
2992
TEST_F(ClientSocketPoolBaseTest,DoNotReuseSocketAfterFlush)2993 TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2994 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2995 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2996
2997 ClientSocketHandle handle;
2998 TestCompletionCallback callback;
2999 EXPECT_EQ(
3000 ERR_IO_PENDING,
3001 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3002 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3003 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3004 pool_.get(), NetLogWithSource()));
3005 EXPECT_THAT(callback.WaitForResult(), IsOk());
3006 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
3007 NetLogSource source = handle.socket()->NetLog().source();
3008
3009 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
3010
3011 handle.Reset();
3012 base::RunLoop().RunUntilIdle();
3013
3014 EXPECT_EQ(
3015 ERR_IO_PENDING,
3016 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3017 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3018 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3019 pool_.get(), NetLogWithSource()));
3020 EXPECT_THAT(callback.WaitForResult(), IsOk());
3021 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
3022
3023 ExpectSocketClosedWithReason(
3024 source, TransportClientSocketPool::kSocketGenerationOutOfDate);
3025 }
3026
3027 class ConnectWithinCallback : public TestCompletionCallbackBase {
3028 public:
ConnectWithinCallback(const ClientSocketPool::GroupId & group_id,const scoped_refptr<ClientSocketPool::SocketParams> & params,TransportClientSocketPool * pool)3029 ConnectWithinCallback(
3030 const ClientSocketPool::GroupId& group_id,
3031 const scoped_refptr<ClientSocketPool::SocketParams>& params,
3032 TransportClientSocketPool* pool)
3033 : group_id_(group_id), params_(params), pool_(pool) {}
3034
3035 ConnectWithinCallback(const ConnectWithinCallback&) = delete;
3036 ConnectWithinCallback& operator=(const ConnectWithinCallback&) = delete;
3037
3038 ~ConnectWithinCallback() override = default;
3039
WaitForNestedResult()3040 int WaitForNestedResult() { return nested_callback_.WaitForResult(); }
3041
callback()3042 CompletionOnceCallback callback() {
3043 return base::BindOnce(&ConnectWithinCallback::OnComplete,
3044 base::Unretained(this));
3045 }
3046
3047 private:
OnComplete(int result)3048 void OnComplete(int result) {
3049 SetResult(result);
3050 EXPECT_EQ(
3051 ERR_IO_PENDING,
3052 handle_.Init(group_id_, params_, std::nullopt, DEFAULT_PRIORITY,
3053 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3054 nested_callback_.callback(),
3055 ClientSocketPool::ProxyAuthCallback(), pool_,
3056 NetLogWithSource()));
3057 }
3058
3059 const ClientSocketPool::GroupId group_id_;
3060 const scoped_refptr<ClientSocketPool::SocketParams> params_;
3061 const raw_ptr<TransportClientSocketPool> pool_;
3062 ClientSocketHandle handle_;
3063 TestCompletionCallback nested_callback_;
3064 };
3065
TEST_F(ClientSocketPoolBaseTest,AbortAllRequestsOnFlush)3066 TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
3067 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3068
3069 // First job will be waiting until it gets aborted.
3070 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3071
3072 ClientSocketHandle handle;
3073 ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
3074 EXPECT_EQ(
3075 ERR_IO_PENDING,
3076 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3077 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3078 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3079 pool_.get(), NetLogWithSource()));
3080
3081 // Second job will be started during the first callback, and will
3082 // asynchronously complete with OK.
3083 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3084 pool_->FlushWithError(ERR_NETWORK_CHANGED, "Network changed");
3085 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_CHANGED));
3086 EXPECT_THAT(callback.WaitForNestedResult(), IsOk());
3087 }
3088
TEST_F(ClientSocketPoolBaseTest,BackupSocketWaitsForHostResolution)3089 TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) {
3090 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3091 true /* enable_backup_connect_jobs */);
3092
3093 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3094 ClientSocketHandle handle;
3095 TestCompletionCallback callback;
3096 EXPECT_EQ(
3097 ERR_IO_PENDING,
3098 handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3099 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3100 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3101 pool_.get(), NetLogWithSource()));
3102 // The backup timer fires but doesn't start a new ConnectJob while resolving
3103 // the hostname.
3104 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3105 FastForwardBy(
3106 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3107 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3108
3109 // Once the ConnectJob has finished resolving the hostname, the backup timer
3110 // will create a ConnectJob when it fires.
3111 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_CONNECTING);
3112 FastForwardBy(
3113 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs));
3114 EXPECT_EQ(2, client_socket_factory_.allocation_count());
3115 }
3116
3117 // Test that no backup socket is created when a ConnectJob connects before it
3118 // completes.
TEST_F(ClientSocketPoolBaseTest,NoBackupSocketWhenConnected)3119 TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) {
3120 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3121 true /* enable_backup_connect_jobs */);
3122
3123 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3124 ClientSocketHandle handle;
3125 TestCompletionCallback callback;
3126 EXPECT_EQ(
3127 ERR_IO_PENDING,
3128 handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3129 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3130 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3131 pool_.get(), NetLogWithSource()));
3132 // The backup timer fires but doesn't start a new ConnectJob while resolving
3133 // the hostname.
3134 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST);
3135 FastForwardBy(
3136 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3137 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3138
3139 client_socket_factory_.SetJobLoadState(0, LOAD_STATE_SSL_HANDSHAKE);
3140 client_socket_factory_.SetJobHasEstablishedConnection(0);
3141 FastForwardBy(
3142 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs * 100));
3143 EXPECT_EQ(1, client_socket_factory_.allocation_count());
3144 }
3145
3146 // Cancel a pending socket request while we're at max sockets,
3147 // and verify that the backup socket firing doesn't cause a crash.
TEST_F(ClientSocketPoolBaseTest,BackupSocketCancelAtMaxSockets)3148 TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
3149 // Max 4 sockets globally, max 4 sockets per group.
3150 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3151 true /* enable_backup_connect_jobs */);
3152
3153 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3154 // timer.
3155 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3156 ClientSocketHandle handle;
3157 TestCompletionCallback callback;
3158 EXPECT_EQ(
3159 ERR_IO_PENDING,
3160 handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3161 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3162 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3163 pool_.get(), NetLogWithSource()));
3164
3165 // Start (MaxSockets - 1) connected sockets to reach max sockets.
3166 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3167 ClientSocketHandle handles[kDefaultMaxSockets];
3168 for (int i = 1; i < kDefaultMaxSockets; ++i) {
3169 EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, std::nullopt,
3170 DEFAULT_PRIORITY, SocketTag(),
3171 ClientSocketPool::RespectLimits::ENABLED,
3172 callback.callback(),
3173 ClientSocketPool::ProxyAuthCallback(),
3174 pool_.get(), NetLogWithSource()));
3175 }
3176
3177 base::RunLoop().RunUntilIdle();
3178
3179 // Cancel the pending request.
3180 handle.Reset();
3181
3182 // Wait for the backup timer to fire (add some slop to ensure it fires)
3183 FastForwardBy(
3184 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3185
3186 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
3187 }
3188
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterCancelingAllRequests)3189 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
3190 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3191 true /* enable_backup_connect_jobs */);
3192
3193 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3194 // timer.
3195 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3196 ClientSocketHandle handle;
3197 TestCompletionCallback callback;
3198 EXPECT_EQ(
3199 ERR_IO_PENDING,
3200 handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3201 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3202 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3203 pool_.get(), NetLogWithSource()));
3204 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3205 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3206 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3207 TestGroupId("bar")));
3208 EXPECT_EQ(
3209 0u, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("bar")));
3210
3211 // Cancel the socket request. This should cancel the backup timer. Wait for
3212 // the backup time to see if it indeed got canceled.
3213 handle.Reset();
3214 // Wait for the backup timer to fire (add some slop to ensure it fires)
3215 FastForwardBy(
3216 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3217 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3218 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3219 }
3220
TEST_F(ClientSocketPoolBaseTest,CancelBackupSocketAfterFinishingAllRequests)3221 TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
3222 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets,
3223 true /* enable_backup_connect_jobs */);
3224
3225 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
3226 // timer.
3227 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3228 ClientSocketHandle handle;
3229 TestCompletionCallback callback;
3230 EXPECT_EQ(
3231 ERR_IO_PENDING,
3232 handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3233 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3234 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3235 pool_.get(), NetLogWithSource()));
3236 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3237 ClientSocketHandle handle2;
3238 TestCompletionCallback callback2;
3239 EXPECT_EQ(
3240 ERR_IO_PENDING,
3241 handle2.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
3242 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3243 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3244 pool_.get(), NetLogWithSource()));
3245 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar")));
3246 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar")));
3247
3248 // Cancel request 1 and then complete request 2. With the requests finished,
3249 // the backup timer should be cancelled.
3250 handle.Reset();
3251 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3252 // Wait for the backup timer to fire (add some slop to ensure it fires)
3253 FastForwardBy(
3254 base::Milliseconds(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
3255 }
3256
3257 // Test delayed socket binding for the case where we have two connects,
3258 // and while one is waiting on a connect, the other frees up.
3259 // The socket waiting on a connect should switch immediately to the freed
3260 // up socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingWaitingForConnect)3261 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
3262 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3263 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3264
3265 ClientSocketHandle handle1;
3266 TestCompletionCallback callback;
3267 EXPECT_EQ(
3268 ERR_IO_PENDING,
3269 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3270 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3271 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3272 pool_.get(), NetLogWithSource()));
3273 EXPECT_THAT(callback.WaitForResult(), IsOk());
3274
3275 // No idle sockets, no pending jobs.
3276 EXPECT_EQ(0, pool_->IdleSocketCount());
3277 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3278
3279 // Create a second socket to the same host, but this one will wait.
3280 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3281 ClientSocketHandle handle2;
3282 EXPECT_EQ(
3283 ERR_IO_PENDING,
3284 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3285 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3286 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3287 pool_.get(), NetLogWithSource()));
3288 // No idle sockets, and one connecting job.
3289 EXPECT_EQ(0, pool_->IdleSocketCount());
3290 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3291
3292 // Return the first handle to the pool. This will initiate the delayed
3293 // binding.
3294 handle1.Reset();
3295
3296 base::RunLoop().RunUntilIdle();
3297
3298 // Still no idle sockets, still one pending connect job.
3299 EXPECT_EQ(0, pool_->IdleSocketCount());
3300 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3301
3302 // The second socket connected, even though it was a Waiting Job.
3303 EXPECT_THAT(callback.WaitForResult(), IsOk());
3304
3305 // And we can see there is still one job waiting.
3306 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3307
3308 // Finally, signal the waiting Connect.
3309 client_socket_factory_.SignalJobs();
3310 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3311
3312 base::RunLoop().RunUntilIdle();
3313 }
3314
3315 // Test delayed socket binding when a group is at capacity and one
3316 // of the group's sockets frees up.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtGroupCapacity)3317 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
3318 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3319 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3320
3321 ClientSocketHandle handle1;
3322 TestCompletionCallback callback;
3323 EXPECT_EQ(
3324 ERR_IO_PENDING,
3325 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3326 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3327 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3328 pool_.get(), NetLogWithSource()));
3329 EXPECT_THAT(callback.WaitForResult(), IsOk());
3330
3331 // No idle sockets, no pending jobs.
3332 EXPECT_EQ(0, pool_->IdleSocketCount());
3333 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3334
3335 // Create a second socket to the same host, but this one will wait.
3336 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3337 ClientSocketHandle handle2;
3338 EXPECT_EQ(
3339 ERR_IO_PENDING,
3340 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3341 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3342 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3343 pool_.get(), NetLogWithSource()));
3344 // No idle sockets, and one connecting job.
3345 EXPECT_EQ(0, pool_->IdleSocketCount());
3346 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3347
3348 // Return the first handle to the pool. This will initiate the delayed
3349 // binding.
3350 handle1.Reset();
3351
3352 base::RunLoop().RunUntilIdle();
3353
3354 // Still no idle sockets, still one pending connect job.
3355 EXPECT_EQ(0, pool_->IdleSocketCount());
3356 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3357
3358 // The second socket connected, even though it was a Waiting Job.
3359 EXPECT_THAT(callback.WaitForResult(), IsOk());
3360
3361 // And we can see there is still one job waiting.
3362 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3363
3364 // Finally, signal the waiting Connect.
3365 client_socket_factory_.SignalJobs();
3366 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3367
3368 base::RunLoop().RunUntilIdle();
3369 }
3370
3371 // Test out the case where we have one socket connected, one
3372 // connecting, when the first socket finishes and goes idle.
3373 // Although the second connection is pending, the second request
3374 // should complete, by taking the first socket's idle socket.
TEST_F(ClientSocketPoolBaseTest,DelayedSocketBindingAtStall)3375 TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
3376 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3377 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3378
3379 ClientSocketHandle handle1;
3380 TestCompletionCallback callback;
3381 EXPECT_EQ(
3382 ERR_IO_PENDING,
3383 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3384 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3385 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3386 pool_.get(), NetLogWithSource()));
3387 EXPECT_THAT(callback.WaitForResult(), IsOk());
3388
3389 // No idle sockets, no pending jobs.
3390 EXPECT_EQ(0, pool_->IdleSocketCount());
3391 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3392
3393 // Create a second socket to the same host, but this one will wait.
3394 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3395 ClientSocketHandle handle2;
3396 EXPECT_EQ(
3397 ERR_IO_PENDING,
3398 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3399 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3400 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
3401 pool_.get(), NetLogWithSource()));
3402 // No idle sockets, and one connecting job.
3403 EXPECT_EQ(0, pool_->IdleSocketCount());
3404 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3405
3406 // Return the first handle to the pool. This will initiate the delayed
3407 // binding.
3408 handle1.Reset();
3409
3410 base::RunLoop().RunUntilIdle();
3411
3412 // Still no idle sockets, still one pending connect job.
3413 EXPECT_EQ(0, pool_->IdleSocketCount());
3414 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3415
3416 // The second socket connected, even though it was a Waiting Job.
3417 EXPECT_THAT(callback.WaitForResult(), IsOk());
3418
3419 // And we can see there is still one job waiting.
3420 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3421
3422 // Finally, signal the waiting Connect.
3423 client_socket_factory_.SignalJobs();
3424 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3425
3426 base::RunLoop().RunUntilIdle();
3427 }
3428
3429 // Cover the case where on an available socket slot, we have one pending
3430 // request that completes synchronously, thereby making the Group empty.
TEST_F(ClientSocketPoolBaseTest,SynchronouslyProcessOnePendingRequest)3431 TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
3432 const int kUnlimitedSockets = 100;
3433 const int kOneSocketPerGroup = 1;
3434 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
3435
3436 // Make the first request asynchronous fail.
3437 // This will free up a socket slot later.
3438 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
3439
3440 ClientSocketHandle handle1;
3441 TestCompletionCallback callback1;
3442 EXPECT_EQ(
3443 ERR_IO_PENDING,
3444 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3445 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3446 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3447 pool_.get(), NetLogWithSource()));
3448 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3449
3450 // Make the second request synchronously fail. This should make the Group
3451 // empty.
3452 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3453 ClientSocketHandle handle2;
3454 TestCompletionCallback callback2;
3455 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
3456 // when created.
3457 EXPECT_EQ(
3458 ERR_IO_PENDING,
3459 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3460 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3461 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3462 pool_.get(), NetLogWithSource()));
3463
3464 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3465
3466 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3467 EXPECT_THAT(callback2.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
3468 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3469 }
3470
TEST_F(ClientSocketPoolBaseTest,PreferUsedSocketToUnusedSocket)3471 TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
3472 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3473
3474 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3475
3476 ClientSocketHandle handle1;
3477 TestCompletionCallback callback1;
3478 EXPECT_EQ(
3479 ERR_IO_PENDING,
3480 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3481 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3482 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3483 pool_.get(), NetLogWithSource()));
3484
3485 ClientSocketHandle handle2;
3486 TestCompletionCallback callback2;
3487 EXPECT_EQ(
3488 ERR_IO_PENDING,
3489 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3490 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3491 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3492 pool_.get(), NetLogWithSource()));
3493 ClientSocketHandle handle3;
3494 TestCompletionCallback callback3;
3495 EXPECT_EQ(
3496 ERR_IO_PENDING,
3497 handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3498 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3499 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3500 pool_.get(), NetLogWithSource()));
3501
3502 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3503 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3504 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3505
3506 // Use the socket.
3507 EXPECT_EQ(1, handle1.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3508 TRAFFIC_ANNOTATION_FOR_TESTS));
3509 EXPECT_EQ(1, handle3.socket()->Write(nullptr, 1, CompletionOnceCallback(),
3510 TRAFFIC_ANNOTATION_FOR_TESTS));
3511
3512 handle1.Reset();
3513 handle2.Reset();
3514 handle3.Reset();
3515
3516 EXPECT_EQ(OK, handle1.Init(
3517 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3518 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3519 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3520 pool_.get(), NetLogWithSource()));
3521 EXPECT_EQ(OK, handle2.Init(
3522 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3523 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3524 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3525 pool_.get(), NetLogWithSource()));
3526 EXPECT_EQ(OK, handle3.Init(
3527 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3528 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3529 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3530 pool_.get(), NetLogWithSource()));
3531
3532 EXPECT_TRUE(handle1.socket()->WasEverUsed());
3533 EXPECT_TRUE(handle2.socket()->WasEverUsed());
3534 EXPECT_FALSE(handle3.socket()->WasEverUsed());
3535 }
3536
TEST_F(ClientSocketPoolBaseTest,RequestSockets)3537 TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
3538 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3539 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3540
3541 TestCompletionCallback preconnect_callback;
3542 EXPECT_EQ(ERR_IO_PENDING,
3543 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3544 preconnect_callback.callback(),
3545 NetLogWithSource()));
3546
3547 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3548 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3549 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3550 TestGroupId("a")));
3551 EXPECT_EQ(2u,
3552 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3553 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3554
3555 ClientSocketHandle handle1;
3556 TestCompletionCallback callback1;
3557 EXPECT_EQ(
3558 ERR_IO_PENDING,
3559 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3560 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3561 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3562 pool_.get(), NetLogWithSource()));
3563
3564 ClientSocketHandle handle2;
3565 TestCompletionCallback callback2;
3566 EXPECT_EQ(
3567 ERR_IO_PENDING,
3568 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3569 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3570 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3571 pool_.get(), NetLogWithSource()));
3572
3573 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3574 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3575 TestGroupId("a")));
3576 EXPECT_EQ(0u,
3577 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3578 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3579
3580 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3581 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3582 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3583 handle1.Reset();
3584 handle2.Reset();
3585
3586 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3587 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3588 TestGroupId("a")));
3589 EXPECT_EQ(0u,
3590 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3591 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3592 }
3593
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveAConnectJob)3594 TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3595 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3596 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3597
3598 ClientSocketHandle handle1;
3599 TestCompletionCallback callback1;
3600 EXPECT_EQ(
3601 ERR_IO_PENDING,
3602 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3603 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3604 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3605 pool_.get(), NetLogWithSource()));
3606
3607 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3608 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3609 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3610 TestGroupId("a")));
3611 EXPECT_EQ(0u,
3612 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3613 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3614
3615 TestCompletionCallback preconnect_callback;
3616 EXPECT_EQ(ERR_IO_PENDING,
3617 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3618 preconnect_callback.callback(),
3619 NetLogWithSource()));
3620
3621 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3622 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3623 TestGroupId("a")));
3624 EXPECT_EQ(1u,
3625 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3626 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3627
3628 ClientSocketHandle handle2;
3629 TestCompletionCallback callback2;
3630 EXPECT_EQ(
3631 ERR_IO_PENDING,
3632 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3633 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3634 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3635 pool_.get(), NetLogWithSource()));
3636
3637 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3638 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3639 TestGroupId("a")));
3640 EXPECT_EQ(0u,
3641 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3642 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3643
3644 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3645 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3646 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3647 handle1.Reset();
3648 handle2.Reset();
3649
3650 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3651 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3652 TestGroupId("a")));
3653 EXPECT_EQ(0u,
3654 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3655 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3656 }
3657
TEST_F(ClientSocketPoolBaseTest,RequestSocketsWhenAlreadyHaveMultipleConnectJob)3658 TEST_F(ClientSocketPoolBaseTest,
3659 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3660 CreatePool(4, 4);
3661 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3662
3663 ClientSocketHandle handle1;
3664 TestCompletionCallback callback1;
3665 EXPECT_EQ(
3666 ERR_IO_PENDING,
3667 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3668 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3669 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3670 pool_.get(), NetLogWithSource()));
3671
3672 ClientSocketHandle handle2;
3673 TestCompletionCallback callback2;
3674 EXPECT_EQ(
3675 ERR_IO_PENDING,
3676 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3677 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3678 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3679 pool_.get(), NetLogWithSource()));
3680
3681 ClientSocketHandle handle3;
3682 TestCompletionCallback callback3;
3683 EXPECT_EQ(
3684 ERR_IO_PENDING,
3685 handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3686 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3687 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
3688 pool_.get(), NetLogWithSource()));
3689
3690 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3691 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3692 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3693 TestGroupId("a")));
3694 EXPECT_EQ(0u,
3695 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3696 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3697
3698 EXPECT_EQ(
3699 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3700 CompletionOnceCallback(), NetLogWithSource()));
3701
3702 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3703 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3704 TestGroupId("a")));
3705 EXPECT_EQ(0u,
3706 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3707 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3708
3709 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3710 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3711 EXPECT_THAT(callback3.WaitForResult(), IsOk());
3712 handle1.Reset();
3713 handle2.Reset();
3714 handle3.Reset();
3715
3716 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3717 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3718 TestGroupId("a")));
3719 EXPECT_EQ(0u,
3720 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3721 EXPECT_EQ(3u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3722 }
3723
TEST_F(ClientSocketPoolBaseTest,RequestSocketsAtMaxSocketLimit)3724 TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3725 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3726 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3727
3728 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3729
3730 TestCompletionCallback preconnect_callback;
3731 EXPECT_EQ(ERR_IO_PENDING,
3732 pool_->RequestSockets(
3733 TestGroupId("a"), params_, std::nullopt, kDefaultMaxSockets,
3734 preconnect_callback.callback(), NetLogWithSource()));
3735
3736 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3737 EXPECT_EQ(kDefaultMaxSockets,
3738 static_cast<int>(
3739 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3740 EXPECT_EQ(
3741 kDefaultMaxSockets,
3742 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3743 TestGroupId("a"))));
3744 EXPECT_EQ(kDefaultMaxSockets,
3745 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3746 TestGroupId("a"))));
3747
3748 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3749
3750 EXPECT_EQ(OK, pool_->RequestSockets(
3751 TestGroupId("b"), params_, std::nullopt, kDefaultMaxSockets,
3752 CompletionOnceCallback(), NetLogWithSource()));
3753
3754 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3755
3756 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3757 }
3758
TEST_F(ClientSocketPoolBaseTest,RequestSocketsHitMaxSocketLimit)3759 TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3760 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3761 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3762
3763 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3764
3765 TestCompletionCallback preconnect_callback1;
3766 EXPECT_EQ(ERR_IO_PENDING,
3767 pool_->RequestSockets(
3768 TestGroupId("a"), params_, std::nullopt, kDefaultMaxSockets - 1,
3769 preconnect_callback1.callback(), NetLogWithSource()));
3770
3771 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3772 EXPECT_EQ(kDefaultMaxSockets - 1,
3773 static_cast<int>(
3774 pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))));
3775 EXPECT_EQ(
3776 kDefaultMaxSockets - 1,
3777 static_cast<int>(pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3778 TestGroupId("a"))));
3779 EXPECT_EQ(kDefaultMaxSockets - 1,
3780 static_cast<int>(pool_->NumUnassignedConnectJobsInGroupForTesting(
3781 TestGroupId("a"))));
3782 EXPECT_FALSE(pool_->IsStalled());
3783
3784 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
3785
3786 TestCompletionCallback preconnect_callback2;
3787 EXPECT_EQ(ERR_IO_PENDING,
3788 pool_->RequestSockets(
3789 TestGroupId("b"), params_, std::nullopt, kDefaultMaxSockets,
3790 preconnect_callback2.callback(), NetLogWithSource()));
3791
3792 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
3793 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3794 EXPECT_FALSE(pool_->IsStalled());
3795
3796 EXPECT_THAT(preconnect_callback1.WaitForResult(), IsOk());
3797 EXPECT_THAT(preconnect_callback2.WaitForResult(), IsOk());
3798 }
3799
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountIdleSockets)3800 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3801 CreatePool(4, 4);
3802 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3803
3804 ClientSocketHandle handle1;
3805 TestCompletionCallback callback1;
3806 EXPECT_EQ(
3807 ERR_IO_PENDING,
3808 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3809 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3810 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3811 pool_.get(), NetLogWithSource()));
3812 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3813 handle1.Reset();
3814
3815 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3816 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3817 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3818 TestGroupId("a")));
3819 EXPECT_EQ(0u,
3820 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3821 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3822
3823 TestCompletionCallback preconnect_callback;
3824 EXPECT_EQ(ERR_IO_PENDING,
3825 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3826 preconnect_callback.callback(),
3827 NetLogWithSource()));
3828
3829 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3830 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3831 TestGroupId("a")));
3832 EXPECT_EQ(1u,
3833 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3834 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3835
3836 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3837 }
3838
TEST_F(ClientSocketPoolBaseTest,RequestSocketsCountActiveSockets)3839 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3840 CreatePool(4, 4);
3841 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3842
3843 ClientSocketHandle handle1;
3844 TestCompletionCallback callback1;
3845 EXPECT_EQ(
3846 ERR_IO_PENDING,
3847 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3848 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3849 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3850 pool_.get(), NetLogWithSource()));
3851 ASSERT_THAT(callback1.WaitForResult(), IsOk());
3852
3853 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3854 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3855 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3856 TestGroupId("a")));
3857 EXPECT_EQ(0u,
3858 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3859 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3860 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3861
3862 TestCompletionCallback preconnect_callback;
3863 EXPECT_EQ(ERR_IO_PENDING,
3864 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3865 preconnect_callback.callback(),
3866 NetLogWithSource()));
3867
3868 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3869 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3870 TestGroupId("a")));
3871 EXPECT_EQ(1u,
3872 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3873 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3874 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3875
3876 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3877 }
3878
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronous)3879 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3880 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3881 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3882
3883 EXPECT_EQ(
3884 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
3885 kDefaultMaxSocketsPerGroup,
3886 CompletionOnceCallback(), NetLogWithSource()));
3887
3888 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3889 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3890 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3891 TestGroupId("a")));
3892 EXPECT_EQ(0u,
3893 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3894 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3895 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
3896
3897 EXPECT_EQ(
3898 OK, pool_->RequestSockets(TestGroupId("b"), params_, std::nullopt,
3899 kDefaultMaxSocketsPerGroup,
3900 CompletionOnceCallback(), NetLogWithSource()));
3901
3902 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
3903 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3904 TestGroupId("b")));
3905 EXPECT_EQ(0u,
3906 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
3907 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
3908 static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("b"))));
3909 }
3910
TEST_F(ClientSocketPoolBaseTest,RequestSocketsSynchronousError)3911 TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3912 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3913 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3914
3915 EXPECT_EQ(
3916 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
3917 kDefaultMaxSocketsPerGroup,
3918 CompletionOnceCallback(), NetLogWithSource()));
3919
3920 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3921
3922 connect_job_factory_->set_job_type(
3923 TestConnectJob::kMockAdditionalErrorStateJob);
3924
3925 EXPECT_EQ(
3926 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
3927 kDefaultMaxSocketsPerGroup,
3928 CompletionOnceCallback(), NetLogWithSource()));
3929
3930 ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
3931 }
3932
TEST_F(ClientSocketPoolBaseTest,RequestSocketsMultipleTimesDoesNothing)3933 TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3934 CreatePool(4, 4);
3935 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3936
3937 TestCompletionCallback preconnect_callback;
3938 EXPECT_EQ(ERR_IO_PENDING,
3939 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3940 preconnect_callback.callback(),
3941 NetLogWithSource()));
3942
3943 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
3944 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3945 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3946 TestGroupId("a")));
3947 EXPECT_EQ(2u,
3948 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3949 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3950 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3951
3952 EXPECT_EQ(
3953 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
3954 CompletionOnceCallback(), NetLogWithSource()));
3955 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3956 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3957 TestGroupId("a")));
3958 EXPECT_EQ(2u,
3959 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3960 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3961 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3962
3963 ClientSocketHandle handle1;
3964 TestCompletionCallback callback1;
3965 EXPECT_EQ(
3966 ERR_IO_PENDING,
3967 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3968 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3969 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
3970 pool_.get(), NetLogWithSource()));
3971
3972 client_socket_factory_.SignalJob(0);
3973 EXPECT_THAT(callback1.WaitForResult(), IsOk());
3974
3975 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3976 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3977 TestGroupId("a")));
3978 EXPECT_EQ(1u,
3979 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
3980 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
3981 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
3982
3983 ClientSocketHandle handle2;
3984 TestCompletionCallback callback2;
3985 EXPECT_EQ(
3986 ERR_IO_PENDING,
3987 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
3988 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
3989 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
3990 pool_.get(), NetLogWithSource()));
3991 client_socket_factory_.SignalJob(0);
3992 EXPECT_THAT(callback2.WaitForResult(), IsOk());
3993 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
3994
3995 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
3996 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
3997 TestGroupId("a")));
3998 EXPECT_EQ(0u,
3999 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4000 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4001 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4002
4003 handle1.Reset();
4004 handle2.Reset();
4005
4006 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4007 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4008 TestGroupId("a")));
4009 EXPECT_EQ(0u,
4010 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4011 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4012 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4013
4014 EXPECT_EQ(
4015 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
4016 CompletionOnceCallback(), NetLogWithSource()));
4017 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4018 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4019 TestGroupId("a")));
4020 EXPECT_EQ(0u,
4021 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4022 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4023 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4024 }
4025
TEST_F(ClientSocketPoolBaseTest,RequestSocketsDifferentNumSockets)4026 TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
4027 CreatePool(4, 4);
4028 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4029
4030 TestCompletionCallback preconnect_callback1;
4031 EXPECT_EQ(ERR_IO_PENDING,
4032 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4033 preconnect_callback1.callback(),
4034 NetLogWithSource()));
4035
4036 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4037 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4038 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4039 TestGroupId("a")));
4040 EXPECT_EQ(1u,
4041 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4042 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4043
4044 TestCompletionCallback preconnect_callback2;
4045 EXPECT_EQ(ERR_IO_PENDING,
4046 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
4047 preconnect_callback2.callback(),
4048 NetLogWithSource()));
4049 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4050 EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4051 TestGroupId("a")));
4052 EXPECT_EQ(2u,
4053 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4054 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4055
4056 TestCompletionCallback preconnect_callback3;
4057 EXPECT_EQ(ERR_IO_PENDING,
4058 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 3,
4059 preconnect_callback3.callback(),
4060 NetLogWithSource()));
4061 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4062 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4063 TestGroupId("a")));
4064 EXPECT_EQ(3u,
4065 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4066 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4067
4068 EXPECT_EQ(
4069 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4070 CompletionOnceCallback(), NetLogWithSource()));
4071 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4072 EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4073 TestGroupId("a")));
4074 EXPECT_EQ(3u,
4075 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4076 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4077 }
4078
TEST_F(ClientSocketPoolBaseTest,PreconnectJobsTakenByNormalRequests)4079 TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
4080 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4081 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4082
4083 TestCompletionCallback preconnect_callback;
4084 EXPECT_EQ(ERR_IO_PENDING,
4085 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4086 preconnect_callback.callback(),
4087 NetLogWithSource()));
4088
4089 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4090 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4091 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4092 TestGroupId("a")));
4093 EXPECT_EQ(1u,
4094 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4095 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4096
4097 ClientSocketHandle handle1;
4098 TestCompletionCallback callback1;
4099 EXPECT_EQ(
4100 ERR_IO_PENDING,
4101 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4102 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4103 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4104 pool_.get(), NetLogWithSource()));
4105
4106 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4107 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4108 TestGroupId("a")));
4109 EXPECT_EQ(0u,
4110 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4111 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4112
4113 client_socket_factory_.SignalJobs();
4114 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4115 EXPECT_THAT(preconnect_callback.WaitForResult(), IsOk());
4116
4117 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4118 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4119 TestGroupId("a")));
4120 EXPECT_EQ(0u,
4121 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4122 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4123 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4124
4125 // Make sure if a preconnected socket is not fully connected when a request
4126 // starts, it has a connect start time.
4127 TestLoadTimingInfoConnectedNotReused(handle1);
4128 handle1.Reset();
4129
4130 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4131 }
4132
4133 // Checks that fully connected preconnect jobs have no connect times, and are
4134 // marked as reused.
TEST_F(ClientSocketPoolBaseTest,ConnectedPreconnectJobsHaveNoConnectTimes)4135 TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) {
4136 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4137 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4138
4139 EXPECT_EQ(
4140 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4141 CompletionOnceCallback(), NetLogWithSource()));
4142
4143 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4144 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4145 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4146 TestGroupId("a")));
4147 EXPECT_EQ(0u,
4148 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4149 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4150
4151 ClientSocketHandle handle;
4152 TestCompletionCallback callback;
4153 EXPECT_EQ(OK, handle.Init(
4154 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4155 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4156 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4157 pool_.get(), NetLogWithSource()));
4158
4159 // Make sure the idle socket was used.
4160 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4161
4162 TestLoadTimingInfoConnectedReused(handle);
4163 handle.Reset();
4164 TestLoadTimingInfoNotConnected(handle);
4165 }
4166
4167 // http://crbug.com/64940 regression test.
TEST_F(ClientSocketPoolBaseTest,PreconnectClosesIdleSocketRemovesGroup)4168 TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
4169 const int kMaxTotalSockets = 3;
4170 const int kMaxSocketsPerGroup = 2;
4171 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
4172 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4173
4174 // Note that group id ordering matters here. "a" comes before "b", so
4175 // CloseOneIdleSocket() will try to close "a"'s idle socket.
4176
4177 // Set up one idle socket in "a".
4178 ClientSocketHandle handle1;
4179 TestCompletionCallback callback1;
4180 EXPECT_EQ(
4181 ERR_IO_PENDING,
4182 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4183 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4184 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4185 pool_.get(), NetLogWithSource()));
4186 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4187 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4188 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4189 TestGroupId("a")));
4190 EXPECT_EQ(0u,
4191 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4192 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4193
4194 client_socket_factory_.SignalJobs();
4195 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4196 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4197 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4198 TestGroupId("a")));
4199 EXPECT_EQ(0u,
4200 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4201 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4202
4203 handle1.Reset();
4204 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4205
4206 // Set up two active sockets in "b".
4207 ClientSocketHandle handle2;
4208 TestCompletionCallback callback2;
4209 EXPECT_EQ(
4210 ERR_IO_PENDING,
4211 handle1.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
4212 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4213 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4214 pool_.get(), NetLogWithSource()));
4215 EXPECT_EQ(
4216 ERR_IO_PENDING,
4217 handle2.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
4218 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4219 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4220 pool_.get(), NetLogWithSource()));
4221
4222 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
4223 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4224 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4225 TestGroupId("b")));
4226 EXPECT_EQ(0u,
4227 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4228 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4229
4230 client_socket_factory_.SignalJobs();
4231 ASSERT_THAT(callback1.WaitForResult(), IsOk());
4232 ASSERT_THAT(callback2.WaitForResult(), IsOk());
4233 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4234 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4235 TestGroupId("b")));
4236 EXPECT_EQ(0u,
4237 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4238 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4239
4240 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
4241 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
4242 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
4243 // sockets for "a", and "b" should still have 2 active sockets.
4244
4245 EXPECT_EQ(
4246 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
4247 CompletionOnceCallback(), NetLogWithSource()));
4248 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4249 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4250 TestGroupId("a")));
4251 EXPECT_EQ(0u,
4252 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4253 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4254 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4255 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4256 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4257 TestGroupId("b")));
4258 EXPECT_EQ(0u,
4259 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4260 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4261 EXPECT_EQ(2, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4262
4263 // Now release the 2 active sockets for "b". This will give us 1 idle socket
4264 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
4265 // "a" should result in closing 1 for "b".
4266 handle1.Reset();
4267 handle2.Reset();
4268 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4269 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4270
4271 TestCompletionCallback preconnect_callback;
4272 EXPECT_EQ(ERR_IO_PENDING,
4273 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
4274 preconnect_callback.callback(),
4275 NetLogWithSource()));
4276 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4277 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4278 TestGroupId("a")));
4279 EXPECT_EQ(1u,
4280 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4281 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4282 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4283 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
4284 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4285 TestGroupId("b")));
4286 EXPECT_EQ(0u,
4287 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("b")));
4288 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
4289 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
4290 }
4291
TEST_F(ClientSocketPoolBaseTest,PreconnectWithoutBackupJob)4292 TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
4293 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4294 true /* enable_backup_connect_jobs */);
4295
4296 // Make the ConnectJob hang until it times out, shorten the timeout.
4297 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4298 connect_job_factory_->set_timeout_duration(base::Milliseconds(500));
4299 TestCompletionCallback preconnect_callback;
4300 EXPECT_EQ(ERR_IO_PENDING,
4301 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4302 preconnect_callback.callback(),
4303 NetLogWithSource()));
4304 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4305 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4306 TestGroupId("a")));
4307 EXPECT_EQ(1u,
4308 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4309 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4310
4311 // Verify the backup timer doesn't create a backup job, by making
4312 // the backup job a pending job instead of a waiting job, so it
4313 // *would* complete if it were created.
4314 base::RunLoop loop;
4315 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4316 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
4317 FROM_HERE, loop.QuitClosure(), base::Seconds(1));
4318 loop.Run();
4319 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
4320 }
4321
TEST_F(ClientSocketPoolBaseTest,PreconnectWithBackupJob)4322 TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
4323 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
4324 true /* enable_backup_connect_jobs */);
4325
4326 // Make the ConnectJob hang forever.
4327 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4328 TestCompletionCallback preconnect_callback;
4329 EXPECT_EQ(ERR_IO_PENDING,
4330 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4331 preconnect_callback.callback(),
4332 NetLogWithSource()));
4333 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4334 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4335 TestGroupId("a")));
4336 EXPECT_EQ(1u,
4337 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4338 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4339 base::RunLoop().RunUntilIdle();
4340
4341 // Make the backup job be a pending job, so it completes normally.
4342 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
4343 ClientSocketHandle handle;
4344 TestCompletionCallback callback;
4345 EXPECT_EQ(
4346 ERR_IO_PENDING,
4347 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4348 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4349 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4350 pool_.get(), NetLogWithSource()));
4351 // Timer has started, but the backup connect job shouldn't be created yet.
4352 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4353 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4354 TestGroupId("a")));
4355 EXPECT_EQ(0u,
4356 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4357 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4358 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4359 ASSERT_THAT(callback.WaitForResult(), IsOk());
4360
4361 // The hung connect job should still be there, but everything else should be
4362 // complete.
4363 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4364 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4365 TestGroupId("a")));
4366 EXPECT_EQ(1u,
4367 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4368 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4369 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4370 }
4371
4372 // Tests that a preconnect that starts out with unread data can still be used.
4373 // http://crbug.com/334467
TEST_F(ClientSocketPoolBaseTest,PreconnectWithUnreadData)4374 TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) {
4375 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4376 connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
4377
4378 EXPECT_EQ(
4379 OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4380 CompletionOnceCallback(), NetLogWithSource()));
4381
4382 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4383 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4384 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4385 TestGroupId("a")));
4386 EXPECT_EQ(0u,
4387 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4388 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4389
4390 // Fail future jobs to be sure that handle receives the preconnected socket
4391 // rather than closing it and making a new one.
4392 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
4393 ClientSocketHandle handle;
4394 TestCompletionCallback callback;
4395 EXPECT_EQ(OK, handle.Init(
4396 TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4397 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4398 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4399 pool_.get(), NetLogWithSource()));
4400
4401 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4402 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4403 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4404 TestGroupId("a")));
4405 EXPECT_EQ(0u,
4406 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4407 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4408 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4409
4410 // Drain the pending read.
4411 EXPECT_EQ(1, handle.socket()->Read(nullptr, 1, CompletionOnceCallback()));
4412
4413 TestLoadTimingInfoConnectedReused(handle);
4414 handle.Reset();
4415
4416 // The socket should be usable now that it's idle again.
4417 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4418 }
4419
TEST_F(ClientSocketPoolBaseTest,RequestGetsAssignedJob)4420 TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) {
4421 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4422 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4423
4424 ClientSocketHandle handle1;
4425 TestCompletionCallback callback1;
4426 EXPECT_EQ(
4427 ERR_IO_PENDING,
4428 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4429 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4430 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4431 pool_.get(), NetLogWithSource()));
4432
4433 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4434 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4435 TestGroupId("a")));
4436 EXPECT_EQ(0u,
4437 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4438 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4439
4440 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4441 &handle1));
4442 }
4443
TEST_F(ClientSocketPoolBaseTest,MultipleRequestsGetAssignedJobs)4444 TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) {
4445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4446 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4447
4448 ClientSocketHandle handle1;
4449 TestCompletionCallback callback1;
4450 EXPECT_EQ(
4451 ERR_IO_PENDING,
4452 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4453 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4454 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4455 pool_.get(), NetLogWithSource()));
4456
4457 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4458 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4459 TestGroupId("a")));
4460 EXPECT_EQ(0u,
4461 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4462 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4463
4464 ClientSocketHandle handle2;
4465 TestCompletionCallback callback2;
4466 EXPECT_EQ(
4467 ERR_IO_PENDING,
4468 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4469 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4470 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4471 pool_.get(), NetLogWithSource()));
4472
4473 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4474 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4475 TestGroupId("a")));
4476 EXPECT_EQ(0u,
4477 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4478 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4479
4480 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4481 &handle1));
4482 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4483 &handle2));
4484
4485 // One job completes. The other request should still have its job.
4486 client_socket_factory_.SignalJob(0);
4487 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4488
4489 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4490 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4491 TestGroupId("a")));
4492 EXPECT_EQ(0u,
4493 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4494 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4495 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4496
4497 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4498 &handle2));
4499 }
4500
TEST_F(ClientSocketPoolBaseTest,PreconnectJobGetsAssignedToRequest)4501 TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) {
4502 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4503 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4504
4505 TestCompletionCallback preconnect_callback;
4506 EXPECT_EQ(ERR_IO_PENDING,
4507 pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
4508 preconnect_callback.callback(),
4509 NetLogWithSource()));
4510
4511 ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
4512 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4513 EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4514 TestGroupId("a")));
4515 EXPECT_EQ(1u,
4516 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4517 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4518
4519 ClientSocketHandle handle1;
4520 TestCompletionCallback callback1;
4521 EXPECT_EQ(
4522 ERR_IO_PENDING,
4523 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4524 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4525 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4526 pool_.get(), NetLogWithSource()));
4527
4528 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4529 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4530 TestGroupId("a")));
4531 EXPECT_EQ(0u,
4532 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4533 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4534
4535 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4536 &handle1));
4537 }
4538
TEST_F(ClientSocketPoolBaseTest,HigherPriorityRequestStealsJob)4539 TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) {
4540 CreatePool(kDefaultMaxSockets, 1);
4541 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4542
4543 ClientSocketHandle handle1;
4544 TestCompletionCallback callback1;
4545 EXPECT_EQ(
4546 ERR_IO_PENDING,
4547 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4548 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4549 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4550 pool_.get(), NetLogWithSource()));
4551
4552 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4553 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4554 TestGroupId("a")));
4555 EXPECT_EQ(0u,
4556 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4557 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4558
4559 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4560 &handle1));
4561
4562 // Insert a higher priority request
4563 ClientSocketHandle handle2;
4564 TestCompletionCallback callback2;
4565 EXPECT_EQ(
4566 ERR_IO_PENDING,
4567 handle2.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
4568 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4569 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4570 pool_.get(), NetLogWithSource()));
4571
4572 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4573 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4574 TestGroupId("a")));
4575 EXPECT_EQ(0u,
4576 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4577 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4578
4579 // The highest priority request should steal the job from the default priority
4580 // request.
4581 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4582 &handle2));
4583 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4584 &handle1));
4585 }
4586
TEST_F(ClientSocketPoolBaseTest,RequestStealsJobFromLowestRequestWithJob)4587 TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) {
4588 CreatePool(3, 3);
4589 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4590
4591 ClientSocketHandle handle_lowest;
4592 TestCompletionCallback callback_lowest;
4593 EXPECT_EQ(
4594 ERR_IO_PENDING,
4595 handle_lowest.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
4596 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4597 callback_lowest.callback(),
4598 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4599 NetLogWithSource()));
4600
4601 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4602 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4603 TestGroupId("a")));
4604 EXPECT_EQ(0u,
4605 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4606 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4607
4608 ClientSocketHandle handle_highest;
4609 TestCompletionCallback callback_highest;
4610 EXPECT_EQ(
4611 ERR_IO_PENDING,
4612 handle_highest.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
4613 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4614 callback_highest.callback(),
4615 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4616 NetLogWithSource()));
4617
4618 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4619 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4620 TestGroupId("a")));
4621 EXPECT_EQ(0u,
4622 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4623 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4624
4625 ClientSocketHandle handle_low;
4626 TestCompletionCallback callback_low;
4627 EXPECT_EQ(ERR_IO_PENDING,
4628 handle_low.Init(
4629 TestGroupId("a"), params_, std::nullopt, LOW, SocketTag(),
4630 ClientSocketPool::RespectLimits::ENABLED,
4631 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
4632 pool_.get(), NetLogWithSource()));
4633
4634 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4635 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4636 TestGroupId("a")));
4637 EXPECT_EQ(0u,
4638 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4639 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4640
4641 ClientSocketHandle handle_lowest2;
4642 TestCompletionCallback callback_lowest2;
4643 EXPECT_EQ(
4644 ERR_IO_PENDING,
4645 handle_lowest2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
4646 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4647 callback_lowest2.callback(),
4648 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4649 NetLogWithSource()));
4650
4651 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4652 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4653 TestGroupId("a")));
4654 EXPECT_EQ(0u,
4655 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4656 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4657
4658 // The top three requests in the queue should have jobs.
4659 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4660 &handle_highest));
4661 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4662 &handle_low));
4663 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4664 &handle_lowest));
4665 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4666 TestGroupId("a"), &handle_lowest2));
4667
4668 // Add another request with medium priority. It should steal the job from the
4669 // lowest priority request with a job.
4670 ClientSocketHandle handle_medium;
4671 TestCompletionCallback callback_medium;
4672 EXPECT_EQ(
4673 ERR_IO_PENDING,
4674 handle_medium.Init(TestGroupId("a"), params_, std::nullopt, MEDIUM,
4675 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4676 callback_medium.callback(),
4677 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4678 NetLogWithSource()));
4679
4680 EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4681 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4682 TestGroupId("a")));
4683 EXPECT_EQ(0u,
4684 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4685 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4686 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4687 &handle_highest));
4688 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4689 &handle_medium));
4690 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4691 &handle_low));
4692 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4693 &handle_lowest));
4694 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(
4695 TestGroupId("a"), &handle_lowest2));
4696 }
4697
TEST_F(ClientSocketPoolBaseTest,ReprioritizeRequestStealsJob)4698 TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) {
4699 CreatePool(kDefaultMaxSockets, 1);
4700 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4701
4702 ClientSocketHandle handle1;
4703 TestCompletionCallback callback1;
4704 EXPECT_EQ(
4705 ERR_IO_PENDING,
4706 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4707 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4708 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4709 pool_.get(), NetLogWithSource()));
4710
4711 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4712 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4713 TestGroupId("a")));
4714 EXPECT_EQ(0u,
4715 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4716 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4717
4718 ClientSocketHandle handle2;
4719 TestCompletionCallback callback2;
4720 EXPECT_EQ(
4721 ERR_IO_PENDING,
4722 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4723 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4724 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4725 pool_.get(), NetLogWithSource()));
4726
4727 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4728 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4729 TestGroupId("a")));
4730 EXPECT_EQ(0u,
4731 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4732 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4733
4734 // The second request doesn't get a job because we are at the limit.
4735 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4736 &handle1));
4737 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4738 &handle2));
4739
4740 // Reprioritizing the second request places it above the first, and it steals
4741 // the job from the first request.
4742 pool_->SetPriority(TestGroupId("a"), &handle2, HIGHEST);
4743 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4744 &handle2));
4745 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4746 &handle1));
4747 }
4748
TEST_F(ClientSocketPoolBaseTest,CancelRequestReassignsJob)4749 TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) {
4750 CreatePool(kDefaultMaxSockets, 1);
4751 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4752
4753 ClientSocketHandle handle1;
4754 TestCompletionCallback callback1;
4755 EXPECT_EQ(
4756 ERR_IO_PENDING,
4757 handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4758 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4759 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4760 pool_.get(), NetLogWithSource()));
4761
4762 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4763 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4764 TestGroupId("a")));
4765 EXPECT_EQ(0u,
4766 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4767 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4768
4769 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4770 &handle1));
4771
4772 ClientSocketHandle handle2;
4773 TestCompletionCallback callback2;
4774 EXPECT_EQ(
4775 ERR_IO_PENDING,
4776 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4777 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4778 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4779 pool_.get(), NetLogWithSource()));
4780
4781 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4782 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4783 TestGroupId("a")));
4784 EXPECT_EQ(0u,
4785 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4786 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4787
4788 // The second request doesn't get a job because we are the limit.
4789 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4790 &handle1));
4791 EXPECT_FALSE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4792 &handle2));
4793
4794 // The second request should get a job upon cancelling the first request.
4795 handle1.Reset();
4796 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4797 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4798 TestGroupId("a")));
4799 EXPECT_EQ(0u,
4800 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4801 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4802
4803 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4804 &handle2));
4805 }
4806
TEST_F(ClientSocketPoolBaseTest,JobCompletionReassignsJob)4807 TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) {
4808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
4809 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
4810
4811 ClientSocketHandle handle1;
4812 TestCompletionCallback callback1;
4813 EXPECT_EQ(
4814 ERR_IO_PENDING,
4815 handle1.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
4816 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4817 callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
4818 pool_.get(), NetLogWithSource()));
4819
4820 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4821 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4822 TestGroupId("a")));
4823 EXPECT_EQ(0u,
4824 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4825 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4826
4827 ClientSocketHandle handle2;
4828 TestCompletionCallback callback2;
4829 EXPECT_EQ(
4830 ERR_IO_PENDING,
4831 handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4832 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4833 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4834 pool_.get(), NetLogWithSource()));
4835
4836 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4837 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4838 TestGroupId("a")));
4839 EXPECT_EQ(0u,
4840 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4841 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4842
4843 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4844 &handle1));
4845 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4846 &handle2));
4847
4848 // The lower-priority job completes first. The higher-priority request should
4849 // get the socket, and the lower-priority request should get the remaining
4850 // job.
4851 client_socket_factory_.SignalJob(1);
4852 EXPECT_THAT(callback1.WaitForResult(), IsOk());
4853 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
4854 EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
4855 TestGroupId("a")));
4856 EXPECT_EQ(0u,
4857 pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a")));
4858 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
4859 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
4860 EXPECT_TRUE(handle1.socket());
4861 EXPECT_TRUE(pool_->RequestInGroupWithHandleHasJobForTesting(TestGroupId("a"),
4862 &handle2));
4863 }
4864
4865 class MockLayeredPool : public HigherLayeredPool {
4866 public:
MockLayeredPool(TransportClientSocketPool * pool,const ClientSocketPool::GroupId & group_id)4867 MockLayeredPool(TransportClientSocketPool* pool,
4868 const ClientSocketPool::GroupId& group_id)
4869 : pool_(pool), group_id_(group_id) {
4870 pool_->AddHigherLayeredPool(this);
4871 }
4872
~MockLayeredPool()4873 ~MockLayeredPool() override { pool_->RemoveHigherLayeredPool(this); }
4874
RequestSocket(TransportClientSocketPool * pool)4875 int RequestSocket(TransportClientSocketPool* pool) {
4876 return handle_.Init(
4877 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4878 std::nullopt, DEFAULT_PRIORITY, SocketTag(),
4879 ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
4880 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4881 }
4882
RequestSocketWithoutLimits(TransportClientSocketPool * pool)4883 int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
4884 return handle_.Init(
4885 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
4886 std::nullopt, MAXIMUM_PRIORITY, SocketTag(),
4887 ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
4888 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
4889 }
4890
ReleaseOneConnection()4891 bool ReleaseOneConnection() {
4892 if (!handle_.is_initialized() || !can_release_connection_) {
4893 return false;
4894 }
4895 handle_.socket()->Disconnect();
4896 handle_.Reset();
4897 return true;
4898 }
4899
set_can_release_connection(bool can_release_connection)4900 void set_can_release_connection(bool can_release_connection) {
4901 can_release_connection_ = can_release_connection;
4902 }
4903
4904 MOCK_METHOD0(CloseOneIdleConnection, bool());
4905
4906 private:
4907 const raw_ptr<TransportClientSocketPool> pool_;
4908 ClientSocketHandle handle_;
4909 TestCompletionCallback callback_;
4910 const ClientSocketPool::GroupId group_id_;
4911 bool can_release_connection_ = true;
4912 };
4913
4914 // Tests the basic case of closing an idle socket in a higher layered pool when
4915 // a new request is issued and the lower layer pool is stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeeded)4916 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
4917 CreatePool(1, 1);
4918 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4919
4920 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4921 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4922 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4923 .WillOnce(
4924 Invoke(&mock_layered_pool, &MockLayeredPool::ReleaseOneConnection));
4925 ClientSocketHandle handle;
4926 TestCompletionCallback callback;
4927 EXPECT_EQ(
4928 ERR_IO_PENDING,
4929 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4930 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4931 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4932 pool_.get(), NetLogWithSource()));
4933 EXPECT_THAT(callback.WaitForResult(), IsOk());
4934 }
4935
4936 // Tests the case that trying to close an idle socket in a higher layered pool
4937 // fails.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededFails)4938 TEST_F(ClientSocketPoolBaseTest,
4939 CloseIdleSocketsHeldByLayeredPoolWhenNeededFails) {
4940 CreatePool(1, 1);
4941 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4942
4943 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("foo"));
4944 mock_layered_pool.set_can_release_connection(false);
4945 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4946 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4947 .WillOnce(
4948 Invoke(&mock_layered_pool, &MockLayeredPool::ReleaseOneConnection));
4949 ClientSocketHandle handle;
4950 TestCompletionCallback callback;
4951 EXPECT_EQ(
4952 ERR_IO_PENDING,
4953 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
4954 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4955 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
4956 pool_.get(), NetLogWithSource()));
4957 base::RunLoop().RunUntilIdle();
4958 EXPECT_FALSE(callback.have_result());
4959 }
4960
4961 // Same as above, but the idle socket is in the same group as the stalled
4962 // socket, and closes the only other request in its group when closing requests
4963 // in higher layered pools. This generally shouldn't happen, but it may be
4964 // possible if a higher level pool issues a request and the request is
4965 // subsequently cancelled. Even if it's not possible, best not to crash.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup)4966 TEST_F(ClientSocketPoolBaseTest,
4967 CloseIdleSocketsHeldByLayeredPoolWhenNeededSameGroup) {
4968 CreatePool(2, 2);
4969 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
4970
4971 // Need a socket in another group for the pool to be stalled (If a group
4972 // has the maximum number of connections already, it's not stalled).
4973 ClientSocketHandle handle1;
4974 TestCompletionCallback callback1;
4975 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
4976 DEFAULT_PRIORITY, SocketTag(),
4977 ClientSocketPool::RespectLimits::ENABLED,
4978 callback1.callback(),
4979 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
4980 NetLogWithSource()));
4981
4982 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
4983 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
4984 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
4985 .WillOnce(
4986 Invoke(&mock_layered_pool, &MockLayeredPool::ReleaseOneConnection));
4987 ClientSocketHandle handle;
4988 TestCompletionCallback callback2;
4989 EXPECT_EQ(ERR_IO_PENDING,
4990 handle.Init(
4991 TestGroupId("group2"), params_, std::nullopt, DEFAULT_PRIORITY,
4992 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
4993 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
4994 pool_.get(), NetLogWithSource()));
4995 EXPECT_THAT(callback2.WaitForResult(), IsOk());
4996 }
4997
4998 // Tests the case when an idle socket can be closed when a new request is
4999 // issued, and the new request belongs to a group that was previously stalled.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded)5000 TEST_F(ClientSocketPoolBaseTest,
5001 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
5002 CreatePool(2, 2);
5003 std::list<TestConnectJob::JobType> job_types;
5004 job_types.push_back(TestConnectJob::kMockJob);
5005 job_types.push_back(TestConnectJob::kMockJob);
5006 job_types.push_back(TestConnectJob::kMockJob);
5007 job_types.push_back(TestConnectJob::kMockJob);
5008 connect_job_factory_->set_job_types(&job_types);
5009
5010 ClientSocketHandle handle1;
5011 TestCompletionCallback callback1;
5012 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
5013 DEFAULT_PRIORITY, SocketTag(),
5014 ClientSocketPool::RespectLimits::ENABLED,
5015 callback1.callback(),
5016 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
5017 NetLogWithSource()));
5018
5019 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
5020 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
5021 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
5022 .WillRepeatedly(
5023 Invoke(&mock_layered_pool, &MockLayeredPool::ReleaseOneConnection));
5024 mock_layered_pool.set_can_release_connection(false);
5025
5026 // The third request is made when the socket pool is in a stalled state.
5027 ClientSocketHandle handle3;
5028 TestCompletionCallback callback3;
5029 EXPECT_EQ(ERR_IO_PENDING,
5030 handle3.Init(
5031 TestGroupId("group3"), params_, std::nullopt, DEFAULT_PRIORITY,
5032 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5033 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5034 pool_.get(), NetLogWithSource()));
5035
5036 base::RunLoop().RunUntilIdle();
5037 EXPECT_FALSE(callback3.have_result());
5038
5039 // The fourth request is made when the pool is no longer stalled. The third
5040 // request should be serviced first, since it was issued first and has the
5041 // same priority.
5042 mock_layered_pool.set_can_release_connection(true);
5043 ClientSocketHandle handle4;
5044 TestCompletionCallback callback4;
5045 EXPECT_EQ(ERR_IO_PENDING,
5046 handle4.Init(
5047 TestGroupId("group3"), params_, std::nullopt, DEFAULT_PRIORITY,
5048 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5049 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5050 pool_.get(), NetLogWithSource()));
5051 EXPECT_THAT(callback3.WaitForResult(), IsOk());
5052 EXPECT_FALSE(callback4.have_result());
5053
5054 // Closing a handle should free up another socket slot.
5055 handle1.Reset();
5056 EXPECT_THAT(callback4.WaitForResult(), IsOk());
5057 }
5058
5059 // Tests the case when an idle socket can be closed when a new request is
5060 // issued, and the new request belongs to a group that was previously stalled.
5061 //
5062 // The two differences from the above test are that the stalled requests are not
5063 // in the same group as the layered pool's request, and the the fourth request
5064 // has a higher priority than the third one, so gets a socket first.
TEST_F(ClientSocketPoolBaseTest,CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2)5065 TEST_F(ClientSocketPoolBaseTest,
5066 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded2) {
5067 CreatePool(2, 2);
5068 std::list<TestConnectJob::JobType> job_types;
5069 job_types.push_back(TestConnectJob::kMockJob);
5070 job_types.push_back(TestConnectJob::kMockJob);
5071 job_types.push_back(TestConnectJob::kMockJob);
5072 job_types.push_back(TestConnectJob::kMockJob);
5073 connect_job_factory_->set_job_types(&job_types);
5074
5075 ClientSocketHandle handle1;
5076 TestCompletionCallback callback1;
5077 EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
5078 DEFAULT_PRIORITY, SocketTag(),
5079 ClientSocketPool::RespectLimits::ENABLED,
5080 callback1.callback(),
5081 ClientSocketPool::ProxyAuthCallback(), pool_.get(),
5082 NetLogWithSource()));
5083
5084 MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2"));
5085 EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk());
5086 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
5087 .WillRepeatedly(
5088 Invoke(&mock_layered_pool, &MockLayeredPool::ReleaseOneConnection));
5089 mock_layered_pool.set_can_release_connection(false);
5090
5091 // The third request is made when the socket pool is in a stalled state.
5092 ClientSocketHandle handle3;
5093 TestCompletionCallback callback3;
5094 EXPECT_EQ(
5095 ERR_IO_PENDING,
5096 handle3.Init(TestGroupId("group3"), params_, std::nullopt, MEDIUM,
5097 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5098 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
5099 pool_.get(), NetLogWithSource()));
5100
5101 base::RunLoop().RunUntilIdle();
5102 EXPECT_FALSE(callback3.have_result());
5103
5104 // The fourth request is made when the pool is no longer stalled. This
5105 // request has a higher priority than the third request, so is serviced first.
5106 mock_layered_pool.set_can_release_connection(true);
5107 ClientSocketHandle handle4;
5108 TestCompletionCallback callback4;
5109 EXPECT_EQ(
5110 ERR_IO_PENDING,
5111 handle4.Init(TestGroupId("group3"), params_, std::nullopt, HIGHEST,
5112 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5113 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
5114 pool_.get(), NetLogWithSource()));
5115 EXPECT_THAT(callback4.WaitForResult(), IsOk());
5116 EXPECT_FALSE(callback3.have_result());
5117
5118 // Closing a handle should free up another socket slot.
5119 handle1.Reset();
5120 EXPECT_THAT(callback3.WaitForResult(), IsOk());
5121 }
5122
TEST_F(ClientSocketPoolBaseTest,CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded)5123 TEST_F(ClientSocketPoolBaseTest,
5124 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
5125 CreatePool(1, 1);
5126 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5127
5128 MockLayeredPool mock_layered_pool1(pool_.get(), TestGroupId("foo"));
5129 EXPECT_THAT(mock_layered_pool1.RequestSocket(pool_.get()), IsOk());
5130 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
5131 .WillRepeatedly(
5132 Invoke(&mock_layered_pool1, &MockLayeredPool::ReleaseOneConnection));
5133 MockLayeredPool mock_layered_pool2(pool_.get(), TestGroupId("bar"));
5134 EXPECT_THAT(mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()),
5135 IsOk());
5136 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
5137 .WillRepeatedly(
5138 Invoke(&mock_layered_pool2, &MockLayeredPool::ReleaseOneConnection));
5139 ClientSocketHandle handle;
5140 TestCompletionCallback callback;
5141 EXPECT_EQ(
5142 ERR_IO_PENDING,
5143 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
5144 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5145 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5146 pool_.get(), NetLogWithSource()));
5147 EXPECT_THAT(callback.WaitForResult(), IsOk());
5148 }
5149
5150 // Test that when a socket pool and group are at their limits, a request
5151 // with RespectLimits::DISABLED triggers creation of a new socket, and gets the
5152 // socket instead of a request with the same priority that was issued earlier,
5153 // but has RespectLimits::ENABLED.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimits)5154 TEST_F(ClientSocketPoolBaseTest, IgnoreLimits) {
5155 CreatePool(1, 1);
5156
5157 // Issue a request to reach the socket pool limit.
5158 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5159 TestGroupId("a"), MAXIMUM_PRIORITY,
5160 ClientSocketPool::RespectLimits::ENABLED));
5161 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5162
5163 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5164
5165 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5166 TestGroupId("a"), MAXIMUM_PRIORITY,
5167 ClientSocketPool::RespectLimits::ENABLED));
5168 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5169
5170 // Issue a request that ignores the limits, so a new ConnectJob is
5171 // created.
5172 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5173 TestGroupId("a"), MAXIMUM_PRIORITY,
5174 ClientSocketPool::RespectLimits::DISABLED));
5175 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5176
5177 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5178 EXPECT_FALSE(request(1)->have_result());
5179 }
5180
5181 // Test that when a socket pool and group are at their limits, a ConnectJob
5182 // issued for a request with RespectLimits::DISABLED is not cancelled when a
5183 // request with RespectLimits::ENABLED issued to the same group is cancelled.
TEST_F(ClientSocketPoolBaseTest,IgnoreLimitsCancelOtherJob)5184 TEST_F(ClientSocketPoolBaseTest, IgnoreLimitsCancelOtherJob) {
5185 CreatePool(1, 1);
5186
5187 // Issue a request to reach the socket pool limit.
5188 EXPECT_EQ(OK, StartRequestWithIgnoreLimits(
5189 TestGroupId("a"), MAXIMUM_PRIORITY,
5190 ClientSocketPool::RespectLimits::ENABLED));
5191 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5192
5193 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5194
5195 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5196 TestGroupId("a"), MAXIMUM_PRIORITY,
5197 ClientSocketPool::RespectLimits::ENABLED));
5198 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5199
5200 // Issue a request with RespectLimits::DISABLED, so a new ConnectJob is
5201 // created.
5202 EXPECT_EQ(ERR_IO_PENDING, StartRequestWithIgnoreLimits(
5203 TestGroupId("a"), MAXIMUM_PRIORITY,
5204 ClientSocketPool::RespectLimits::DISABLED));
5205 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5206
5207 // Cancel the pending request with RespectLimits::ENABLED. The ConnectJob
5208 // should not be cancelled.
5209 request(1)->handle()->Reset();
5210 ASSERT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5211
5212 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
5213 EXPECT_FALSE(request(1)->have_result());
5214 }
5215
TEST_F(ClientSocketPoolBaseTest,ProxyAuthNoAuthCallback)5216 TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) {
5217 CreatePool(1, 1);
5218
5219 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5220
5221 ClientSocketHandle handle;
5222 TestCompletionCallback callback;
5223 EXPECT_EQ(
5224 ERR_IO_PENDING,
5225 handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
5226 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5227 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5228 pool_.get(), NetLogWithSource()));
5229
5230 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5231
5232 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_AUTH_REQUESTED));
5233 EXPECT_FALSE(handle.is_initialized());
5234 EXPECT_FALSE(handle.socket());
5235
5236 // The group should now be empty, and thus be deleted.
5237 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5238 }
5239
5240 class TestAuthHelper {
5241 public:
5242 TestAuthHelper() = default;
5243
5244 TestAuthHelper(const TestAuthHelper&) = delete;
5245 TestAuthHelper& operator=(const TestAuthHelper&) = delete;
5246
5247 ~TestAuthHelper() = default;
5248
InitHandle(scoped_refptr<ClientSocketPool::SocketParams> params,TransportClientSocketPool * pool,RequestPriority priority=DEFAULT_PRIORITY,ClientSocketPool::RespectLimits respect_limits=ClientSocketPool::RespectLimits::ENABLED,const ClientSocketPool::GroupId & group_id_in=TestGroupId ("a"))5249 void InitHandle(
5250 scoped_refptr<ClientSocketPool::SocketParams> params,
5251 TransportClientSocketPool* pool,
5252 RequestPriority priority = DEFAULT_PRIORITY,
5253 ClientSocketPool::RespectLimits respect_limits =
5254 ClientSocketPool::RespectLimits::ENABLED,
5255 const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
5256 EXPECT_EQ(ERR_IO_PENDING,
5257 handle_.Init(group_id_in, params, std::nullopt, priority,
5258 SocketTag(), respect_limits, callback_.callback(),
5259 base::BindRepeating(&TestAuthHelper::AuthCallback,
5260 base::Unretained(this)),
5261 pool, NetLogWithSource()));
5262 }
5263
WaitForAuth()5264 void WaitForAuth() {
5265 run_loop_ = std::make_unique<base::RunLoop>();
5266 run_loop_->Run();
5267 run_loop_.reset();
5268 }
5269
WaitForAuthAndRestartSync()5270 void WaitForAuthAndRestartSync() {
5271 restart_sync_ = true;
5272 WaitForAuth();
5273 restart_sync_ = false;
5274 }
5275
WaitForAuthAndResetHandleSync()5276 void WaitForAuthAndResetHandleSync() {
5277 reset_handle_sync_ = true;
5278 WaitForAuth();
5279 reset_handle_sync_ = false;
5280 }
5281
RestartWithAuth()5282 void RestartWithAuth() {
5283 DCHECK(restart_with_auth_callback_);
5284 std::move(restart_with_auth_callback_).Run();
5285 }
5286
WaitForResult()5287 int WaitForResult() {
5288 int result = callback_.WaitForResult();
5289 // There shouldn't be any callback waiting to be invoked once the request is
5290 // complete.
5291 EXPECT_FALSE(restart_with_auth_callback_);
5292 // The socket should only be initialized on success.
5293 EXPECT_EQ(result == OK, handle_.is_initialized());
5294 EXPECT_EQ(result == OK, handle_.socket() != nullptr);
5295 return result;
5296 }
5297
handle()5298 ClientSocketHandle* handle() { return &handle_; }
auth_count() const5299 int auth_count() const { return auth_count_; }
have_result() const5300 int have_result() const { return callback_.have_result(); }
5301
5302 private:
AuthCallback(const HttpResponseInfo & response,HttpAuthController * auth_controller,base::OnceClosure restart_with_auth_callback)5303 void AuthCallback(const HttpResponseInfo& response,
5304 HttpAuthController* auth_controller,
5305 base::OnceClosure restart_with_auth_callback) {
5306 EXPECT_FALSE(restart_with_auth_callback_);
5307 EXPECT_TRUE(restart_with_auth_callback);
5308
5309 // Once there's a result, this method shouldn't be invoked again.
5310 EXPECT_FALSE(callback_.have_result());
5311
5312 ++auth_count_;
5313 run_loop_->Quit();
5314 if (restart_sync_) {
5315 std::move(restart_with_auth_callback).Run();
5316 return;
5317 }
5318
5319 restart_with_auth_callback_ = std::move(restart_with_auth_callback);
5320
5321 if (reset_handle_sync_) {
5322 handle_.Reset();
5323 return;
5324 }
5325 }
5326
5327 std::unique_ptr<base::RunLoop> run_loop_;
5328 base::OnceClosure restart_with_auth_callback_;
5329
5330 bool restart_sync_ = false;
5331 bool reset_handle_sync_ = false;
5332
5333 ClientSocketHandle handle_;
5334 int auth_count_ = 0;
5335 TestCompletionCallback callback_;
5336 };
5337
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnce)5338 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnce) {
5339 CreatePool(1, 1);
5340 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5341
5342 TestAuthHelper auth_helper;
5343 auth_helper.InitHandle(params_, pool_.get());
5344 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5345 EXPECT_EQ(LOAD_STATE_CONNECTING,
5346 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5347
5348 auth_helper.WaitForAuth();
5349 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5350 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5351 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5352
5353 auth_helper.RestartWithAuth();
5354 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5355 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5356 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5357
5358 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5359 EXPECT_EQ(1, auth_helper.auth_count());
5360 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5361 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5362 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5363 EXPECT_EQ(0, pool_->IdleSocketCount());
5364 }
5365
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSync)5366 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSync) {
5367 CreatePool(1, 1);
5368 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5369
5370 TestAuthHelper auth_helper;
5371 auth_helper.InitHandle(params_, pool_.get());
5372 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5373 EXPECT_EQ(LOAD_STATE_CONNECTING,
5374 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5375
5376 auth_helper.WaitForAuthAndRestartSync();
5377 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5378 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5379 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5380
5381 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5382 EXPECT_EQ(1, auth_helper.auth_count());
5383 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5384 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5385 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5386 EXPECT_EQ(0, pool_->IdleSocketCount());
5387 }
5388
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFails)5389 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFails) {
5390 CreatePool(1, 1);
5391 connect_job_factory_->set_job_type(
5392 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5393
5394 TestAuthHelper auth_helper;
5395 auth_helper.InitHandle(params_, pool_.get());
5396 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5397
5398 auth_helper.WaitForAuth();
5399 auth_helper.RestartWithAuth();
5400 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5401
5402 EXPECT_EQ(1, auth_helper.auth_count());
5403 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5404 EXPECT_EQ(0, pool_->IdleSocketCount());
5405 }
5406
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceSyncFails)5407 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceSyncFails) {
5408 CreatePool(1, 1);
5409 connect_job_factory_->set_job_type(
5410 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5411
5412 TestAuthHelper auth_helper;
5413 auth_helper.InitHandle(params_, pool_.get());
5414 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5415
5416 auth_helper.WaitForAuthAndRestartSync();
5417 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5418
5419 EXPECT_EQ(1, auth_helper.auth_count());
5420 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5421 EXPECT_EQ(0, pool_->IdleSocketCount());
5422 }
5423
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandle)5424 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandle) {
5425 CreatePool(1, 1);
5426 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5427
5428 TestAuthHelper auth_helper;
5429 auth_helper.InitHandle(params_, pool_.get());
5430 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5431
5432 auth_helper.WaitForAuth();
5433 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5434
5435 auth_helper.handle()->Reset();
5436
5437 EXPECT_EQ(1, auth_helper.auth_count());
5438 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5439 EXPECT_EQ(0, pool_->IdleSocketCount());
5440 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5441 EXPECT_FALSE(auth_helper.handle()->socket());
5442 }
5443
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceDeleteHandleSync)5444 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceDeleteHandleSync) {
5445 CreatePool(1, 1);
5446 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5447
5448 TestAuthHelper auth_helper;
5449 auth_helper.InitHandle(params_, pool_.get());
5450 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5451
5452 auth_helper.WaitForAuthAndResetHandleSync();
5453 EXPECT_EQ(1, auth_helper.auth_count());
5454 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5455 EXPECT_EQ(0, pool_->IdleSocketCount());
5456 EXPECT_FALSE(auth_helper.handle()->is_initialized());
5457 EXPECT_FALSE(auth_helper.handle()->socket());
5458 }
5459
TEST_F(ClientSocketPoolBaseTest,ProxyAuthOnceFlushWithError)5460 TEST_F(ClientSocketPoolBaseTest, ProxyAuthOnceFlushWithError) {
5461 CreatePool(1, 1);
5462 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5463
5464 TestAuthHelper auth_helper;
5465 auth_helper.InitHandle(params_, pool_.get());
5466 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5467
5468 auth_helper.WaitForAuth();
5469
5470 pool_->FlushWithError(ERR_FAILED, "Network changed");
5471 base::RunLoop().RunUntilIdle();
5472
5473 // When flushing the socket pool, bound sockets should delay returning the
5474 // error until completion.
5475 EXPECT_FALSE(auth_helper.have_result());
5476 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5477 EXPECT_EQ(0, pool_->IdleSocketCount());
5478
5479 auth_helper.RestartWithAuth();
5480 // The callback should be called asynchronously.
5481 EXPECT_FALSE(auth_helper.have_result());
5482
5483 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_FAILED));
5484 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5485 EXPECT_EQ(0, pool_->IdleSocketCount());
5486 }
5487
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwice)5488 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwice) {
5489 CreatePool(1, 1);
5490 connect_job_factory_->set_job_type(
5491 TestConnectJob::kMockAuthChallengeTwiceJob);
5492
5493 TestAuthHelper auth_helper;
5494 auth_helper.InitHandle(params_, pool_.get());
5495 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5496 EXPECT_EQ(LOAD_STATE_CONNECTING,
5497 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5498
5499 auth_helper.WaitForAuth();
5500 auth_helper.RestartWithAuth();
5501 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5502 EXPECT_EQ(1, auth_helper.auth_count());
5503 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5504 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5505
5506 auth_helper.WaitForAuth();
5507 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5508 EXPECT_EQ(2, auth_helper.auth_count());
5509 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5510 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5511
5512 auth_helper.RestartWithAuth();
5513 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5514 EXPECT_EQ(2, auth_helper.auth_count());
5515 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
5516 pool_->GetLoadState(TestGroupId("a"), auth_helper.handle()));
5517
5518 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5519 EXPECT_EQ(2, auth_helper.auth_count());
5520 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5521 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5522 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5523 EXPECT_EQ(0, pool_->IdleSocketCount());
5524 }
5525
TEST_F(ClientSocketPoolBaseTest,ProxyAuthTwiceFails)5526 TEST_F(ClientSocketPoolBaseTest, ProxyAuthTwiceFails) {
5527 CreatePool(1, 1);
5528 connect_job_factory_->set_job_type(
5529 TestConnectJob::kMockAuthChallengeTwiceFailingJob);
5530
5531 TestAuthHelper auth_helper;
5532 auth_helper.InitHandle(params_, pool_.get());
5533 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5534
5535 auth_helper.WaitForAuth();
5536 auth_helper.RestartWithAuth();
5537 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5538 EXPECT_EQ(1, auth_helper.auth_count());
5539
5540 auth_helper.WaitForAuth();
5541 auth_helper.RestartWithAuth();
5542 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5543 EXPECT_EQ(2, auth_helper.auth_count());
5544
5545 EXPECT_THAT(auth_helper.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
5546 EXPECT_EQ(2, auth_helper.auth_count());
5547 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5548 EXPECT_EQ(0, pool_->IdleSocketCount());
5549 }
5550
5551 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5552 // created, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequest)5553 TEST_F(ClientSocketPoolBaseTest,
5554 ProxyAuthCreateNewConnectJobOnDestroyBoundRequest) {
5555 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5556 connect_job_factory_->set_job_type(
5557 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5558
5559 // First request creates a ConnectJob.
5560 TestAuthHelper auth_helper1;
5561 auth_helper1.InitHandle(params_, pool_.get());
5562 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5563
5564 // A second request come in, but no new ConnectJob is needed, since the limit
5565 // has been reached.
5566 TestAuthHelper auth_helper2;
5567 auth_helper2.InitHandle(params_, pool_.get());
5568 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5569
5570 // Run until the auth callback for the first request is invoked.
5571 auth_helper1.WaitForAuth();
5572 EXPECT_EQ(0, auth_helper2.auth_count());
5573 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5574 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5575 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5576
5577 // Make connect jobs succeed, then cancel the first request, which should
5578 // destroy the bound ConnectJob, and cause a new ConnectJob to start.
5579 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5580 auth_helper1.handle()->Reset();
5581 EXPECT_EQ(0, auth_helper2.auth_count());
5582 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5583
5584 // The second ConnectJob should succeed.
5585 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5586 EXPECT_EQ(0, auth_helper2.auth_count());
5587 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5588 }
5589
5590 // Makes sure that when a bound request is destroyed, a new ConnectJob is
5591 // created for another group, if needed.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups)5592 TEST_F(ClientSocketPoolBaseTest,
5593 ProxyAuthCreateNewConnectJobOnDestroyBoundRequestDifferentGroups) {
5594 CreatePool(1 /* max_sockets */, 1 /* max_sockets_per_group */);
5595 connect_job_factory_->set_job_type(
5596 TestConnectJob::kMockAuthChallengeOnceFailingJob);
5597
5598 // First request creates a ConnectJob.
5599 TestAuthHelper auth_helper1;
5600 auth_helper1.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY);
5601 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5602
5603 // A second request come in, but no new ConnectJob is needed, since the limit
5604 // has been reached.
5605 TestAuthHelper auth_helper2;
5606 auth_helper2.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5607 ClientSocketPool::RespectLimits::ENABLED,
5608 TestGroupId("b"));
5609 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5610 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5611
5612 // Run until the auth callback for the first request is invoked.
5613 auth_helper1.WaitForAuth();
5614 EXPECT_EQ(0, auth_helper2.auth_count());
5615 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5616 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5617 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5618 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5619 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b")));
5620 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("b")));
5621
5622 // Make connect jobs succeed, then cancel the first request, which should
5623 // destroy the bound ConnectJob, and cause a new ConnectJob to start for the
5624 // other group.
5625 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
5626 auth_helper1.handle()->Reset();
5627 EXPECT_EQ(0, auth_helper2.auth_count());
5628 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5629 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5630
5631 // The second ConnectJob should succeed.
5632 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5633 EXPECT_EQ(0, auth_helper2.auth_count());
5634 EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a")));
5635 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b")));
5636 }
5637
5638 // Test that once an auth challenge is bound, that's the request that gets all
5639 // subsequent calls and the socket itself.
TEST_F(ClientSocketPoolBaseTest,ProxyAuthStaysBound)5640 TEST_F(ClientSocketPoolBaseTest, ProxyAuthStaysBound) {
5641 CreatePool(1, 1);
5642 connect_job_factory_->set_job_type(
5643 TestConnectJob::kMockAuthChallengeTwiceJob);
5644
5645 // First request creates a ConnectJob.
5646 TestAuthHelper auth_helper1;
5647 auth_helper1.InitHandle(params_, pool_.get(), LOWEST);
5648 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5649
5650 // A second, higher priority request is made.
5651 TestAuthHelper auth_helper2;
5652 auth_helper2.InitHandle(params_, pool_.get(), LOW);
5653 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5654
5655 // Run until the auth callback for the second request is invoked.
5656 auth_helper2.WaitForAuth();
5657 EXPECT_EQ(0, auth_helper1.auth_count());
5658 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5659 EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5660 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
5661
5662 // Start a higher priority job. It shouldn't be able to steal |auth_helper2|'s
5663 // ConnectJob.
5664 TestAuthHelper auth_helper3;
5665 auth_helper3.InitHandle(params_, pool_.get(), HIGHEST);
5666 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5667
5668 // Start a higher job that ignores limits, creating a hanging socket. It
5669 // shouldn't be able to steal |auth_helper2|'s ConnectJob.
5670 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5671 TestAuthHelper auth_helper4;
5672 auth_helper4.InitHandle(params_, pool_.get(), HIGHEST,
5673 ClientSocketPool::RespectLimits::DISABLED);
5674 EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5675
5676 // Restart with auth, and |auth_helper2|'s auth method should be invoked
5677 // again.
5678 auth_helper2.RestartWithAuth();
5679 auth_helper2.WaitForAuth();
5680 EXPECT_EQ(0, auth_helper1.auth_count());
5681 EXPECT_FALSE(auth_helper1.have_result());
5682 EXPECT_EQ(2, auth_helper2.auth_count());
5683 EXPECT_FALSE(auth_helper2.have_result());
5684 EXPECT_EQ(0, auth_helper3.auth_count());
5685 EXPECT_FALSE(auth_helper3.have_result());
5686 EXPECT_EQ(0, auth_helper4.auth_count());
5687 EXPECT_FALSE(auth_helper4.have_result());
5688
5689 // Advance auth again, and |auth_helper2| should get the socket.
5690 auth_helper2.RestartWithAuth();
5691 EXPECT_THAT(auth_helper2.WaitForResult(), IsOk());
5692 // The hung ConnectJob for the RespectLimits::DISABLED request is still in the
5693 // socket pool.
5694 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
5695 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a")));
5696 EXPECT_EQ(0, auth_helper1.auth_count());
5697 EXPECT_FALSE(auth_helper1.have_result());
5698 EXPECT_EQ(0, auth_helper3.auth_count());
5699 EXPECT_FALSE(auth_helper3.have_result());
5700 EXPECT_EQ(0, auth_helper4.auth_count());
5701 EXPECT_FALSE(auth_helper4.have_result());
5702
5703 // If the socket is returned to the socket pool, the RespectLimits::DISABLED
5704 // socket request should be able to claim it.
5705 auth_helper2.handle()->Reset();
5706 EXPECT_THAT(auth_helper4.WaitForResult(), IsOk());
5707 EXPECT_EQ(0, auth_helper1.auth_count());
5708 EXPECT_FALSE(auth_helper1.have_result());
5709 EXPECT_EQ(0, auth_helper3.auth_count());
5710 EXPECT_FALSE(auth_helper3.have_result());
5711 EXPECT_EQ(0, auth_helper4.auth_count());
5712 }
5713
5714 enum class RefreshType {
5715 kServer,
5716 kProxy,
5717 };
5718
5719 // Common base class to test RefreshGroup() when called from either
5720 // OnSSLConfigForServersChanged() matching a specific group or the pool's proxy.
5721 //
5722 // Tests which test behavior specific to one or the other case should use
5723 // ClientSocketPoolBaseTest directly. In particular, there is no "other group"
5724 // when the pool's proxy matches.
5725 class ClientSocketPoolBaseRefreshTest
5726 : public ClientSocketPoolBaseTest,
5727 public testing::WithParamInterface<RefreshType> {
5728 public:
CreatePoolForRefresh(int max_sockets,int max_sockets_per_group,bool enable_backup_connect_jobs=false)5729 void CreatePoolForRefresh(int max_sockets,
5730 int max_sockets_per_group,
5731 bool enable_backup_connect_jobs = false) {
5732 switch (GetParam()) {
5733 case RefreshType::kServer:
5734 CreatePool(max_sockets, max_sockets_per_group,
5735 enable_backup_connect_jobs);
5736 break;
5737 case RefreshType::kProxy:
5738 CreatePoolWithIdleTimeouts(
5739 max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
5740 ClientSocketPool::used_idle_socket_timeout(),
5741 enable_backup_connect_jobs,
5742 PacResultElementToProxyChain("HTTPS myproxy:70"));
5743 break;
5744 }
5745 }
5746
GetGroupId()5747 static ClientSocketPool::GroupId GetGroupId() {
5748 return TestGroupId("a", 443, url::kHttpsScheme);
5749 }
5750
GetGroupIdInPartition()5751 static ClientSocketPool::GroupId GetGroupIdInPartition() {
5752 // Note this GroupId will match GetGroupId() unless
5753 // kPartitionConnectionsByNetworkAnonymizationKey is enabled.
5754 const SchemefulSite kSite(GURL("https://b/"));
5755 const auto kNetworkAnonymizationKey =
5756 NetworkAnonymizationKey::CreateSameSite(kSite);
5757 return TestGroupId("a", 443, url::kHttpsScheme,
5758 PrivacyMode::PRIVACY_MODE_DISABLED,
5759 kNetworkAnonymizationKey);
5760 }
5761
OnSSLConfigForServersChanged()5762 void OnSSLConfigForServersChanged() {
5763 switch (GetParam()) {
5764 case RefreshType::kServer:
5765 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5766 break;
5767 case RefreshType::kProxy:
5768 pool_->OnSSLConfigForServersChanged({HostPortPair("myproxy", 70)});
5769 break;
5770 }
5771 }
5772 };
5773
5774 INSTANTIATE_TEST_SUITE_P(RefreshType,
5775 ClientSocketPoolBaseRefreshTest,
5776 ::testing::Values(RefreshType::kServer,
5777 RefreshType::kProxy));
5778
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupCreatesNewConnectJobs)5779 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupCreatesNewConnectJobs) {
5780 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5781 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5782
5783 // First job will be waiting until it gets aborted.
5784 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
5785
5786 ClientSocketHandle handle;
5787 TestCompletionCallback callback;
5788 EXPECT_THAT(
5789 handle.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
5790 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5791 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5792 pool_.get(), NetLogWithSource()),
5793 IsError(ERR_IO_PENDING));
5794
5795 // Switch connect job types, so creating a new ConnectJob will result in
5796 // success.
5797 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
5798
5799 OnSSLConfigForServersChanged();
5800 EXPECT_EQ(OK, callback.WaitForResult());
5801 ASSERT_TRUE(handle.socket());
5802 EXPECT_EQ(0, pool_->IdleSocketCount());
5803 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5804 EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(kGroupId));
5805 EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5806 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5807 }
5808
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupClosesIdleConnectJobs)5809 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupClosesIdleConnectJobs) {
5810 base::test::ScopedFeatureList feature_list;
5811 feature_list.InitAndEnableFeature(
5812 features::kPartitionConnectionsByNetworkIsolationKey);
5813
5814 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5815 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5816 const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
5817
5818 EXPECT_EQ(
5819 OK, pool_->RequestSockets(kGroupId, params_, std::nullopt, 2,
5820 CompletionOnceCallback(), NetLogWithSource()));
5821
5822 EXPECT_EQ(
5823 OK, pool_->RequestSockets(kGroupIdInPartition, params_, std::nullopt, 2,
5824 CompletionOnceCallback(), NetLogWithSource()));
5825 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5826 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
5827 EXPECT_EQ(4, pool_->IdleSocketCount());
5828 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId));
5829 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupIdInPartition));
5830
5831 OnSSLConfigForServersChanged();
5832 EXPECT_EQ(0, pool_->IdleSocketCount());
5833 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5834 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdInPartition));
5835 }
5836
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup)5837 TEST_F(ClientSocketPoolBaseTest,
5838 RefreshGroupDoesNotCloseIdleConnectJobsInOtherGroup) {
5839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5840 const ClientSocketPool::GroupId kGroupId =
5841 TestGroupId("a", 443, url::kHttpsScheme);
5842 const ClientSocketPool::GroupId kOtherGroupId =
5843 TestGroupId("b", 443, url::kHttpsScheme);
5844
5845 EXPECT_EQ(
5846 OK, pool_->RequestSockets(kOtherGroupId, params_, std::nullopt, 2,
5847 CompletionOnceCallback(), NetLogWithSource()));
5848 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5849 EXPECT_EQ(2, pool_->IdleSocketCount());
5850 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5851
5852 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5853 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5854 EXPECT_EQ(2, pool_->IdleSocketCount());
5855 EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5856 }
5857
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupPreventsSocketReuse)5858 TEST_P(ClientSocketPoolBaseRefreshTest, RefreshGroupPreventsSocketReuse) {
5859 CreatePoolForRefresh(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5860 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5861
5862 ClientSocketHandle handle;
5863 TestCompletionCallback callback;
5864 EXPECT_THAT(
5865 handle.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
5866 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5867 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5868 pool_.get(), NetLogWithSource()),
5869 IsOk());
5870 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5871 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
5872
5873 OnSSLConfigForServersChanged();
5874
5875 handle.Reset();
5876 EXPECT_EQ(0, pool_->IdleSocketCount());
5877 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
5878 }
5879
TEST_F(ClientSocketPoolBaseTest,RefreshGroupDoesNotPreventSocketReuseInOtherGroup)5880 TEST_F(ClientSocketPoolBaseTest,
5881 RefreshGroupDoesNotPreventSocketReuseInOtherGroup) {
5882 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
5883 const ClientSocketPool::GroupId kGroupId =
5884 TestGroupId("a", 443, url::kHttpsScheme);
5885 const ClientSocketPool::GroupId kOtherGroupId =
5886 TestGroupId("b", 443, url::kHttpsScheme);
5887
5888 ClientSocketHandle handle;
5889 TestCompletionCallback callback;
5890 EXPECT_THAT(
5891 handle.Init(kOtherGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
5892 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5893 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5894 pool_.get(), NetLogWithSource()),
5895 IsOk());
5896 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5897 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
5898
5899 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
5900
5901 handle.Reset();
5902 EXPECT_EQ(1, pool_->IdleSocketCount());
5903 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
5904 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
5905 }
5906
TEST_P(ClientSocketPoolBaseRefreshTest,RefreshGroupReplacesBoundConnectJobOnConnect)5907 TEST_P(ClientSocketPoolBaseRefreshTest,
5908 RefreshGroupReplacesBoundConnectJobOnConnect) {
5909 CreatePoolForRefresh(1, 1);
5910 const ClientSocketPool::GroupId kGroupId = GetGroupId();
5911 connect_job_factory_->set_job_type(TestConnectJob::kMockAuthChallengeOnceJob);
5912
5913 TestAuthHelper auth_helper;
5914 auth_helper.InitHandle(params_, pool_.get(), DEFAULT_PRIORITY,
5915 ClientSocketPool::RespectLimits::ENABLED, kGroupId);
5916 EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(kGroupId));
5917
5918 auth_helper.WaitForAuth();
5919
5920 // This should update the generation, but not cancel the old ConnectJob - it's
5921 // not safe to do anything while waiting on the original ConnectJob.
5922 OnSSLConfigForServersChanged();
5923
5924 // Providing auth credentials and restarting the request with them will cause
5925 // the ConnectJob to complete successfully, but the result will be discarded
5926 // because of the generation mismatch.
5927 auth_helper.RestartWithAuth();
5928
5929 // Despite using ConnectJobs that simulate a single challenge, a second
5930 // challenge will be seen, due to using a new ConnectJob.
5931 auth_helper.WaitForAuth();
5932 auth_helper.RestartWithAuth();
5933
5934 EXPECT_THAT(auth_helper.WaitForResult(), IsOk());
5935 EXPECT_TRUE(auth_helper.handle()->socket());
5936 EXPECT_EQ(2, auth_helper.auth_count());
5937
5938 // When released, the socket will be returned to the socket pool, and
5939 // available for reuse.
5940 auth_helper.handle()->Reset();
5941 EXPECT_EQ(1, pool_->IdleSocketCount());
5942 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
5943 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId));
5944 }
5945
TEST_F(ClientSocketPoolBaseTest,RefreshProxyRefreshesAllGroups)5946 TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
5947 // Create a proxy chain containing `myproxy` (which is refreshed) and
5948 // nonrefreshedproxy (which is not), verifying that if any proxy in a chain is
5949 // refreshed, all groups are refreshed.
5950 ProxyChain proxy_chain({
5951 PacResultElementToProxyServer("HTTPS myproxy:70"),
5952 PacResultElementToProxyServer("HTTPS nonrefreshedproxy:70"),
5953 });
5954 CreatePoolWithIdleTimeouts(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
5955 kUnusedIdleSocketTimeout,
5956 ClientSocketPool::used_idle_socket_timeout(),
5957 false /* no backup connect jobs */, proxy_chain);
5958
5959 const ClientSocketPool::GroupId kGroupId1 =
5960 TestGroupId("a", 443, url::kHttpsScheme);
5961 const ClientSocketPool::GroupId kGroupId2 =
5962 TestGroupId("b", 443, url::kHttpsScheme);
5963 const ClientSocketPool::GroupId kGroupId3 =
5964 TestGroupId("c", 443, url::kHttpsScheme);
5965
5966 // Make three sockets in three different groups. The third socket is released
5967 // to the pool as idle.
5968 ClientSocketHandle handle1, handle2, handle3;
5969 TestCompletionCallback callback;
5970 EXPECT_THAT(
5971 handle1.Init(kGroupId1, params_, std::nullopt, DEFAULT_PRIORITY,
5972 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5973 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5974 pool_.get(), NetLogWithSource()),
5975 IsOk());
5976 EXPECT_THAT(
5977 handle2.Init(kGroupId2, params_, std::nullopt, DEFAULT_PRIORITY,
5978 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5979 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5980 pool_.get(), NetLogWithSource()),
5981 IsOk());
5982 EXPECT_THAT(
5983 handle3.Init(kGroupId3, params_, std::nullopt, DEFAULT_PRIORITY,
5984 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
5985 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
5986 pool_.get(), NetLogWithSource()),
5987 IsOk());
5988 handle3.Reset();
5989 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
5990 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
5991 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
5992 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
5993 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
5994 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
5995
5996 // Changes to some other proxy do not affect the pool. The idle socket remains
5997 // alive and closing |handle2| makes the socket available for the pool.
5998 pool_->OnSSLConfigForServersChanged({HostPortPair("someotherproxy", 70)});
5999
6000 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
6001 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
6002 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
6003 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId2));
6004 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId3));
6005 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId3));
6006
6007 handle2.Reset();
6008 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId2));
6009 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kGroupId2));
6010
6011 // Changes to the matching proxy refreshes all groups.
6012 pool_->OnSSLConfigForServersChanged({HostPortPair("myproxy", 70)});
6013
6014 // Idle sockets are closed.
6015 EXPECT_EQ(0, pool_->IdleSocketCount());
6016 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId2));
6017 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId3));
6018
6019 // The active socket, however, continues to be active.
6020 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId1));
6021 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId1));
6022
6023 // Closing it does not make it available for the pool.
6024 handle1.Reset();
6025 EXPECT_EQ(0, pool_->IdleSocketCount());
6026 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId1));
6027 }
6028
TEST_F(ClientSocketPoolBaseTest,RefreshBothPrivacyAndNormalSockets)6029 TEST_F(ClientSocketPoolBaseTest, RefreshBothPrivacyAndNormalSockets) {
6030 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
6031
6032 const ClientSocketPool::GroupId kGroupId = TestGroupId(
6033 "a", 443, url::kHttpsScheme, PrivacyMode::PRIVACY_MODE_DISABLED);
6034 const ClientSocketPool::GroupId kGroupIdPrivacy = TestGroupId(
6035 "a", 443, url::kHttpsScheme, PrivacyMode::PRIVACY_MODE_ENABLED);
6036 const ClientSocketPool::GroupId kOtherGroupId =
6037 TestGroupId("b", 443, url::kHttpsScheme);
6038
6039 // Make a socket in each groups.
6040 ClientSocketHandle handle1, handle2, handle3;
6041 TestCompletionCallback callback;
6042 EXPECT_THAT(
6043 handle1.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
6044 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6045 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6046 pool_.get(), NetLogWithSource()),
6047 IsOk());
6048 EXPECT_THAT(
6049 handle2.Init(kGroupIdPrivacy, params_, std::nullopt, DEFAULT_PRIORITY,
6050 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6051 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6052 pool_.get(), NetLogWithSource()),
6053 IsOk());
6054 EXPECT_THAT(
6055 handle3.Init(kOtherGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
6056 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
6057 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
6058 pool_.get(), NetLogWithSource()),
6059 IsOk());
6060 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
6061 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
6062 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6063 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
6064 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6065 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
6066
6067 pool_->OnSSLConfigForServersChanged({HostPortPair("a", 443)});
6068
6069 // Active sockets continue to be active.
6070 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
6071 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId));
6072 ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6073 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupIdPrivacy));
6074 ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6075 EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId));
6076
6077 // Closing them leaves kOtherGroupId alone, but kGroupId and kGroupIdPrivacy
6078 // are unusable.
6079 handle1.Reset();
6080 handle2.Reset();
6081 handle3.Reset();
6082 EXPECT_EQ(1, pool_->IdleSocketCount());
6083 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupId));
6084 EXPECT_FALSE(pool_->HasGroupForTesting(kGroupIdPrivacy));
6085 EXPECT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
6086 EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(kOtherGroupId));
6087 }
6088
6089 } // namespace
6090
6091 } // namespace net
6092