xref: /aosp_15_r20/external/cronet/net/socket/connect_job_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/socket/connect_job.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/base/address_list.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/resolve_error_info.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/socket/connect_job_test_util.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_tag.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_test_util.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
21*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace net {
24*6777b538SAndroid Build Coastguard Worker namespace {
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker class TestConnectJob : public ConnectJob {
27*6777b538SAndroid Build Coastguard Worker  public:
28*6777b538SAndroid Build Coastguard Worker   enum class JobType {
29*6777b538SAndroid Build Coastguard Worker     kSyncSuccess,
30*6777b538SAndroid Build Coastguard Worker     kAsyncSuccess,
31*6777b538SAndroid Build Coastguard Worker     kHung,
32*6777b538SAndroid Build Coastguard Worker   };
33*6777b538SAndroid Build Coastguard Worker 
TestConnectJob(JobType job_type,base::TimeDelta timeout_duration,const CommonConnectJobParams * common_connect_job_params,ConnectJob::Delegate * delegate)34*6777b538SAndroid Build Coastguard Worker   TestConnectJob(JobType job_type,
35*6777b538SAndroid Build Coastguard Worker                  base::TimeDelta timeout_duration,
36*6777b538SAndroid Build Coastguard Worker                  const CommonConnectJobParams* common_connect_job_params,
37*6777b538SAndroid Build Coastguard Worker                  ConnectJob::Delegate* delegate)
38*6777b538SAndroid Build Coastguard Worker       : ConnectJob(DEFAULT_PRIORITY,
39*6777b538SAndroid Build Coastguard Worker                    SocketTag(),
40*6777b538SAndroid Build Coastguard Worker                    timeout_duration,
41*6777b538SAndroid Build Coastguard Worker                    common_connect_job_params,
42*6777b538SAndroid Build Coastguard Worker                    delegate,
43*6777b538SAndroid Build Coastguard Worker                    nullptr /* net_log */,
44*6777b538SAndroid Build Coastguard Worker                    NetLogSourceType::TRANSPORT_CONNECT_JOB,
45*6777b538SAndroid Build Coastguard Worker                    NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
46*6777b538SAndroid Build Coastguard Worker         job_type_(job_type) {
47*6777b538SAndroid Build Coastguard Worker     switch (job_type_) {
48*6777b538SAndroid Build Coastguard Worker       case JobType::kSyncSuccess:
49*6777b538SAndroid Build Coastguard Worker         socket_data_provider_.set_connect_data(MockConnect(SYNCHRONOUS, OK));
50*6777b538SAndroid Build Coastguard Worker         return;
51*6777b538SAndroid Build Coastguard Worker       case JobType::kAsyncSuccess:
52*6777b538SAndroid Build Coastguard Worker         socket_data_provider_.set_connect_data(MockConnect(ASYNC, OK));
53*6777b538SAndroid Build Coastguard Worker         return;
54*6777b538SAndroid Build Coastguard Worker       case JobType::kHung:
55*6777b538SAndroid Build Coastguard Worker         socket_data_provider_.set_connect_data(
56*6777b538SAndroid Build Coastguard Worker             MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
57*6777b538SAndroid Build Coastguard Worker         return;
58*6777b538SAndroid Build Coastguard Worker     }
59*6777b538SAndroid Build Coastguard Worker   }
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   TestConnectJob(const TestConnectJob&) = delete;
62*6777b538SAndroid Build Coastguard Worker   TestConnectJob& operator=(const TestConnectJob&) = delete;
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker   // From ConnectJob:
GetLoadState() const65*6777b538SAndroid Build Coastguard Worker   LoadState GetLoadState() const override { return LOAD_STATE_IDLE; }
HasEstablishedConnection() const66*6777b538SAndroid Build Coastguard Worker   bool HasEstablishedConnection() const override { return false; }
GetResolveErrorInfo() const67*6777b538SAndroid Build Coastguard Worker   ResolveErrorInfo GetResolveErrorInfo() const override {
68*6777b538SAndroid Build Coastguard Worker     return ResolveErrorInfo(net::OK);
69*6777b538SAndroid Build Coastguard Worker   }
ConnectInternal()70*6777b538SAndroid Build Coastguard Worker   int ConnectInternal() override {
71*6777b538SAndroid Build Coastguard Worker     SetSocket(std::make_unique<MockTCPClientSocket>(
72*6777b538SAndroid Build Coastguard Worker                   AddressList(), net_log().net_log(), &socket_data_provider_),
73*6777b538SAndroid Build Coastguard Worker               std::nullopt /* dns_aliases */);
74*6777b538SAndroid Build Coastguard Worker     return socket()->Connect(base::BindOnce(
75*6777b538SAndroid Build Coastguard Worker         &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
76*6777b538SAndroid Build Coastguard Worker   }
ChangePriorityInternal(RequestPriority priority)77*6777b538SAndroid Build Coastguard Worker   void ChangePriorityInternal(RequestPriority priority) override {
78*6777b538SAndroid Build Coastguard Worker     last_seen_priority_ = priority;
79*6777b538SAndroid Build Coastguard Worker   }
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   using ConnectJob::ResetTimer;
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   // The priority seen during the most recent call to ChangePriorityInternal().
last_seen_priority() const84*6777b538SAndroid Build Coastguard Worker   RequestPriority last_seen_priority() const { return last_seen_priority_; }
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker  protected:
87*6777b538SAndroid Build Coastguard Worker   const JobType job_type_;
88*6777b538SAndroid Build Coastguard Worker   StaticSocketDataProvider socket_data_provider_;
89*6777b538SAndroid Build Coastguard Worker   RequestPriority last_seen_priority_ = DEFAULT_PRIORITY;
90*6777b538SAndroid Build Coastguard Worker };
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker class ConnectJobTest : public testing::Test {
93*6777b538SAndroid Build Coastguard Worker  public:
ConnectJobTest()94*6777b538SAndroid Build Coastguard Worker   ConnectJobTest()
95*6777b538SAndroid Build Coastguard Worker       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
96*6777b538SAndroid Build Coastguard Worker         common_connect_job_params_(
97*6777b538SAndroid Build Coastguard Worker             /*client_socket_factory=*/nullptr,
98*6777b538SAndroid Build Coastguard Worker             /*host_resolver=*/nullptr,
99*6777b538SAndroid Build Coastguard Worker             /*http_auth_cache=*/nullptr,
100*6777b538SAndroid Build Coastguard Worker             /*http_auth_handler_factory=*/nullptr,
101*6777b538SAndroid Build Coastguard Worker             /*spdy_session_pool=*/nullptr,
102*6777b538SAndroid Build Coastguard Worker             /*quic_supported_versions=*/nullptr,
103*6777b538SAndroid Build Coastguard Worker             /*quic_session_pool=*/nullptr,
104*6777b538SAndroid Build Coastguard Worker             /*proxy_delegate=*/nullptr,
105*6777b538SAndroid Build Coastguard Worker             /*http_user_agent_settings=*/nullptr,
106*6777b538SAndroid Build Coastguard Worker             /*ssl_client_context=*/nullptr,
107*6777b538SAndroid Build Coastguard Worker             /*socket_performance_watcher_factory=*/nullptr,
108*6777b538SAndroid Build Coastguard Worker             /*network_quality_estimator=*/nullptr,
109*6777b538SAndroid Build Coastguard Worker             NetLog::Get(),
110*6777b538SAndroid Build Coastguard Worker             /*websocket_endpoint_lock_manager=*/nullptr,
111*6777b538SAndroid Build Coastguard Worker             /*http_server_properties*/ nullptr,
112*6777b538SAndroid Build Coastguard Worker             /*alpn_protos=*/nullptr,
113*6777b538SAndroid Build Coastguard Worker             /*application_settings=*/nullptr,
114*6777b538SAndroid Build Coastguard Worker             /*ignore_certificate_errors=*/nullptr,
115*6777b538SAndroid Build Coastguard Worker             /*early_data_enabled=*/nullptr) {}
116*6777b538SAndroid Build Coastguard Worker   ~ConnectJobTest() override = default;
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker  protected:
119*6777b538SAndroid Build Coastguard Worker   base::test::TaskEnvironment task_environment_;
120*6777b538SAndroid Build Coastguard Worker   RecordingNetLogObserver net_log_observer_;
121*6777b538SAndroid Build Coastguard Worker   const CommonConnectJobParams common_connect_job_params_;
122*6777b538SAndroid Build Coastguard Worker   TestConnectJobDelegate delegate_;
123*6777b538SAndroid Build Coastguard Worker };
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker // Even though a timeout is specified, it doesn't time out on a synchronous
126*6777b538SAndroid Build Coastguard Worker // completion.
TEST_F(ConnectJobTest,NoTimeoutOnSyncCompletion)127*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, NoTimeoutOnSyncCompletion) {
128*6777b538SAndroid Build Coastguard Worker   TestConnectJob job(TestConnectJob::JobType::kSyncSuccess,
129*6777b538SAndroid Build Coastguard Worker                      base::Microseconds(1), &common_connect_job_params_,
130*6777b538SAndroid Build Coastguard Worker                      &delegate_);
131*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(job.Connect(), test::IsOk());
132*6777b538SAndroid Build Coastguard Worker }
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker // Even though a timeout is specified, it doesn't time out on an asynchronous
135*6777b538SAndroid Build Coastguard Worker // completion.
TEST_F(ConnectJobTest,NoTimeoutOnAsyncCompletion)136*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, NoTimeoutOnAsyncCompletion) {
137*6777b538SAndroid Build Coastguard Worker   TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess, base::Minutes(1),
138*6777b538SAndroid Build Coastguard Worker                      &common_connect_job_params_, &delegate_);
139*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
140*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker // Job shouldn't timeout when passed a TimeDelta of zero.
TEST_F(ConnectJobTest,NoTimeoutWithNoTimeDelta)144*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, NoTimeoutWithNoTimeDelta) {
145*6777b538SAndroid Build Coastguard Worker   TestConnectJob job(TestConnectJob::JobType::kHung, base::TimeDelta(),
146*6777b538SAndroid Build Coastguard Worker                      &common_connect_job_params_, &delegate_);
147*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
148*6777b538SAndroid Build Coastguard Worker   task_environment_.RunUntilIdle();
149*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(delegate_.has_result());
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker // Make sure that ChangePriority() works, and new priority is visible to
153*6777b538SAndroid Build Coastguard Worker // subclasses during the SetPriorityInternal call.
TEST_F(ConnectJobTest,SetPriority)154*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, SetPriority) {
155*6777b538SAndroid Build Coastguard Worker   TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
156*6777b538SAndroid Build Coastguard Worker                      base::Microseconds(1), &common_connect_job_params_,
157*6777b538SAndroid Build Coastguard Worker                      &delegate_);
158*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   job.ChangePriority(HIGHEST);
161*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HIGHEST, job.priority());
162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HIGHEST, job.last_seen_priority());
163*6777b538SAndroid Build Coastguard Worker 
164*6777b538SAndroid Build Coastguard Worker   job.ChangePriority(MEDIUM);
165*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MEDIUM, job.priority());
166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(MEDIUM, job.last_seen_priority());
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker 
TEST_F(ConnectJobTest,TimedOut)171*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, TimedOut) {
172*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTimeout = base::Hours(1);
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TestConnectJob> job =
175*6777b538SAndroid Build Coastguard Worker       std::make_unique<TestConnectJob>(TestConnectJob::JobType::kHung, kTimeout,
176*6777b538SAndroid Build Coastguard Worker                                        &common_connect_job_params_, &delegate_);
177*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(job->Connect(), test::IsError(ERR_IO_PENDING));
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   // Nothing should happen before the specified time.
180*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
181*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
182*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(delegate_.has_result());
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   // At which point the job should time out.
185*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(base::Milliseconds(1));
186*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   // Have to delete the job for it to log the end event.
189*6777b538SAndroid Build Coastguard Worker   job.reset();
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   auto entries = net_log_observer_.GetEntries();
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(6u, entries.size());
194*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
195*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsBeginEvent(
196*6777b538SAndroid Build Coastguard Worker       entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEvent(entries, 2,
198*6777b538SAndroid Build Coastguard Worker                                NetLogEventType::CONNECT_JOB_SET_SOCKET,
199*6777b538SAndroid Build Coastguard Worker                                NetLogEventPhase::NONE));
200*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEvent(entries, 3,
201*6777b538SAndroid Build Coastguard Worker                                NetLogEventType::CONNECT_JOB_TIMED_OUT,
202*6777b538SAndroid Build Coastguard Worker                                NetLogEventPhase::NONE));
203*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(
204*6777b538SAndroid Build Coastguard Worker       entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
205*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
206*6777b538SAndroid Build Coastguard Worker }
207*6777b538SAndroid Build Coastguard Worker 
TEST_F(ConnectJobTest,TimedOutWithRestartedTimer)208*6777b538SAndroid Build Coastguard Worker TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
209*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTimeout = base::Hours(1);
210*6777b538SAndroid Build Coastguard Worker 
211*6777b538SAndroid Build Coastguard Worker   TestConnectJob job(TestConnectJob::JobType::kHung, kTimeout,
212*6777b538SAndroid Build Coastguard Worker                      &common_connect_job_params_, &delegate_);
213*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   // Nothing should happen before the specified time.
216*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
217*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
218*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(delegate_.has_result());
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   // Make sure restarting the timer is respected.
221*6777b538SAndroid Build Coastguard Worker   job.ResetTimer(kTimeout);
222*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
223*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
224*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(delegate_.has_result());
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker   task_environment_.FastForwardBy(base::Milliseconds(1));
227*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker }  // namespace
231*6777b538SAndroid Build Coastguard Worker }  // namespace net
232