123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/socket/connect_job.h"
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/run_loop.h"
- #include "base/test/task_environment.h"
- #include "net/base/address_list.h"
- #include "net/base/net_errors.h"
- #include "net/base/request_priority.h"
- #include "net/dns/public/resolve_error_info.h"
- #include "net/log/test_net_log.h"
- #include "net/log/test_net_log_util.h"
- #include "net/socket/connect_job_test_util.h"
- #include "net/socket/socket_tag.h"
- #include "net/socket/socket_test_util.h"
- #include "net/test/gtest_util.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace net {
- namespace {
- class TestConnectJob : public ConnectJob {
- public:
- enum class JobType {
- kSyncSuccess,
- kAsyncSuccess,
- kHung,
- };
- TestConnectJob(JobType job_type,
- base::TimeDelta timeout_duration,
- const CommonConnectJobParams* common_connect_job_params,
- ConnectJob::Delegate* delegate)
- : ConnectJob(DEFAULT_PRIORITY,
- SocketTag(),
- timeout_duration,
- common_connect_job_params,
- delegate,
- nullptr /* net_log */,
- NetLogSourceType::TRANSPORT_CONNECT_JOB,
- NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT),
- job_type_(job_type) {
- switch (job_type_) {
- case JobType::kSyncSuccess:
- socket_data_provider_.set_connect_data(MockConnect(SYNCHRONOUS, OK));
- return;
- case JobType::kAsyncSuccess:
- socket_data_provider_.set_connect_data(MockConnect(ASYNC, OK));
- return;
- case JobType::kHung:
- socket_data_provider_.set_connect_data(
- MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
- return;
- }
- }
- TestConnectJob(const TestConnectJob&) = delete;
- TestConnectJob& operator=(const TestConnectJob&) = delete;
- // From ConnectJob:
- LoadState GetLoadState() const override { return LOAD_STATE_IDLE; }
- bool HasEstablishedConnection() const override { return false; }
- ResolveErrorInfo GetResolveErrorInfo() const override {
- return ResolveErrorInfo(net::OK);
- }
- int ConnectInternal() override {
- SetSocket(std::make_unique<MockTCPClientSocket>(
- AddressList(), net_log().net_log(), &socket_data_provider_),
- absl::nullopt /* dns_aliases */);
- return socket()->Connect(base::BindOnce(
- &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
- }
- void ChangePriorityInternal(RequestPriority priority) override {
- last_seen_priority_ = priority;
- }
- using ConnectJob::ResetTimer;
- // The priority seen during the most recent call to ChangePriorityInternal().
- RequestPriority last_seen_priority() const { return last_seen_priority_; }
- protected:
- const JobType job_type_;
- StaticSocketDataProvider socket_data_provider_;
- RequestPriority last_seen_priority_ = DEFAULT_PRIORITY;
- };
- class ConnectJobTest : public testing::Test {
- public:
- ConnectJobTest()
- : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
- common_connect_job_params_(
- nullptr /* client_socket_factory */,
- nullptr /* host_resolver */,
- nullptr /* http_auth_cache */,
- nullptr /* http_auth_handler_factory */,
- nullptr /* spdy_session_pool */,
- nullptr /* quic_supported_versions */,
- nullptr /* quic_stream_factory */,
- nullptr /* proxy_delegate */,
- nullptr /* http_user_agent_settings */,
- nullptr /* ssl_client_context */,
- nullptr /* socket_performance_watcher_factory */,
- nullptr /* network_quality_estimator */,
- NetLog::Get(),
- nullptr /* websocket_endpoint_lock_manager */) {}
- ~ConnectJobTest() override = default;
- protected:
- base::test::TaskEnvironment task_environment_;
- RecordingNetLogObserver net_log_observer_;
- const CommonConnectJobParams common_connect_job_params_;
- TestConnectJobDelegate delegate_;
- };
- // Even though a timeout is specified, it doesn't time out on a synchronous
- // completion.
- TEST_F(ConnectJobTest, NoTimeoutOnSyncCompletion) {
- TestConnectJob job(TestConnectJob::JobType::kSyncSuccess,
- base::Microseconds(1), &common_connect_job_params_,
- &delegate_);
- EXPECT_THAT(job.Connect(), test::IsOk());
- }
- // Even though a timeout is specified, it doesn't time out on an asynchronous
- // completion.
- TEST_F(ConnectJobTest, NoTimeoutOnAsyncCompletion) {
- TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess, base::Minutes(1),
- &common_connect_job_params_, &delegate_);
- ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
- EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
- }
- // Job shouldn't timeout when passed a TimeDelta of zero.
- TEST_F(ConnectJobTest, NoTimeoutWithNoTimeDelta) {
- TestConnectJob job(TestConnectJob::JobType::kHung, base::TimeDelta(),
- &common_connect_job_params_, &delegate_);
- ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
- task_environment_.RunUntilIdle();
- EXPECT_FALSE(delegate_.has_result());
- }
- // Make sure that ChangePriority() works, and new priority is visible to
- // subclasses during the SetPriorityInternal call.
- TEST_F(ConnectJobTest, SetPriority) {
- TestConnectJob job(TestConnectJob::JobType::kAsyncSuccess,
- base::Microseconds(1), &common_connect_job_params_,
- &delegate_);
- ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
- job.ChangePriority(HIGHEST);
- EXPECT_EQ(HIGHEST, job.priority());
- EXPECT_EQ(HIGHEST, job.last_seen_priority());
- job.ChangePriority(MEDIUM);
- EXPECT_EQ(MEDIUM, job.priority());
- EXPECT_EQ(MEDIUM, job.last_seen_priority());
- EXPECT_THAT(delegate_.WaitForResult(), test::IsOk());
- }
- TEST_F(ConnectJobTest, TimedOut) {
- const base::TimeDelta kTimeout = base::Hours(1);
- std::unique_ptr<TestConnectJob> job =
- std::make_unique<TestConnectJob>(TestConnectJob::JobType::kHung, kTimeout,
- &common_connect_job_params_, &delegate_);
- ASSERT_THAT(job->Connect(), test::IsError(ERR_IO_PENDING));
- // Nothing should happen before the specified time.
- task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(delegate_.has_result());
- // At which point the job should time out.
- task_environment_.FastForwardBy(base::Milliseconds(1));
- EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
- // Have to delete the job for it to log the end event.
- job.reset();
- auto entries = net_log_observer_.GetEntries();
- EXPECT_EQ(6u, entries.size());
- EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLogEventType::CONNECT_JOB));
- EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
- EXPECT_TRUE(LogContainsEvent(entries, 2,
- NetLogEventType::CONNECT_JOB_SET_SOCKET,
- NetLogEventPhase::NONE));
- EXPECT_TRUE(LogContainsEvent(entries, 3,
- NetLogEventType::CONNECT_JOB_TIMED_OUT,
- NetLogEventPhase::NONE));
- EXPECT_TRUE(LogContainsEndEvent(
- entries, 4, NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT));
- EXPECT_TRUE(LogContainsEndEvent(entries, 5, NetLogEventType::CONNECT_JOB));
- }
- TEST_F(ConnectJobTest, TimedOutWithRestartedTimer) {
- const base::TimeDelta kTimeout = base::Hours(1);
- TestConnectJob job(TestConnectJob::JobType::kHung, kTimeout,
- &common_connect_job_params_, &delegate_);
- ASSERT_THAT(job.Connect(), test::IsError(ERR_IO_PENDING));
- // Nothing should happen before the specified time.
- task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(delegate_.has_result());
- // Make sure restarting the timer is respected.
- job.ResetTimer(kTimeout);
- task_environment_.FastForwardBy(kTimeout - base::Milliseconds(1));
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(delegate_.has_result());
- task_environment_.FastForwardBy(base::Milliseconds(1));
- EXPECT_THAT(delegate_.WaitForResult(), test::IsError(ERR_TIMED_OUT));
- }
- } // namespace
- } // namespace net
|