Index: net/http/http_stream_factory_impl_job_controller_unittest.cc |
diff --git a/net/http/http_stream_factory_impl_job_controller_unittest.cc b/net/http/http_stream_factory_impl_job_controller_unittest.cc |
index 2ff3e1b88068fea781e30486ca0fa8a4173cb521..489efd0b0033e03f70a594967d786cddcea709dc 100644 |
--- a/net/http/http_stream_factory_impl_job_controller_unittest.cc |
+++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc |
@@ -9,7 +9,6 @@ |
#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
-#include "base/strings/stringprintf.h" |
#include "base/test/histogram_tester.h" |
#include "base/test/scoped_feature_list.h" |
#include "base/test/scoped_mock_time_message_loop_task_runner.h" |
@@ -17,7 +16,6 @@ |
#include "net/base/test_proxy_delegate.h" |
#include "net/dns/mock_host_resolver.h" |
#include "net/http/http_basic_stream.h" |
-#include "net/http/http_stream_factory_impl_job.h" |
#include "net/http/http_stream_factory_impl_request.h" |
#include "net/http/http_stream_factory_test_util.h" |
#include "net/log/net_log_with_source.h" |
@@ -25,12 +23,7 @@ |
#include "net/proxy/proxy_config_service_fixed.h" |
#include "net/proxy/proxy_info.h" |
#include "net/proxy/proxy_service.h" |
-#include "net/quic/chromium/mock_crypto_client_stream_factory.h" |
-#include "net/quic/chromium/mock_quic_data.h" |
-#include "net/quic/chromium/quic_stream_factory.h" |
#include "net/quic/chromium/quic_stream_factory_peer.h" |
-#include "net/quic/chromium/quic_test_packet_maker.h" |
-#include "net/quic/test_tools/mock_random.h" |
#include "net/socket/socket_test_util.h" |
#include "net/spdy/chromium/spdy_test_util_common.h" |
#include "testing/gmock/include/gmock/gmock.h" |
@@ -44,28 +37,6 @@ namespace net { |
namespace { |
-const char kServerHostname[] = "www.example.com"; |
- |
-// List of errors that are used in the proxy resolution tests. |
-const int proxy_test_mock_errors[] = { |
- ERR_PROXY_CONNECTION_FAILED, |
- ERR_NAME_NOT_RESOLVED, |
- ERR_ADDRESS_UNREACHABLE, |
- ERR_CONNECTION_CLOSED, |
- ERR_CONNECTION_TIMED_OUT, |
- ERR_CONNECTION_RESET, |
- ERR_CONNECTION_REFUSED, |
- ERR_CONNECTION_ABORTED, |
- ERR_TIMED_OUT, |
- ERR_TUNNEL_CONNECTION_FAILED, |
- ERR_SOCKS_CONNECTION_FAILED, |
- ERR_PROXY_CERTIFICATE_INVALID, |
- ERR_QUIC_PROTOCOL_ERROR, |
- ERR_QUIC_HANDSHAKE_FAILED, |
- ERR_SSL_PROTOCOL_ERROR, |
- ERR_MSG_TOO_BIG, |
-}; |
- |
void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, |
const ProxyInfo& used_proxy_info, |
HttpStream* stream) { |
@@ -142,12 +113,6 @@ class HttpStreamFactoryImplJobPeer { |
static int GetNumStreams(const HttpStreamFactoryImpl::Job* job) { |
return job->num_streams_; |
} |
- |
- // Return SpdySessionKey of |job|. |
- static const SpdySessionKey GetSpdySessionKey( |
- const HttpStreamFactoryImpl::Job* job) { |
- return job->GetSpdySessionKey(); |
- } |
}; |
class JobControllerPeer { |
@@ -156,22 +121,12 @@ class JobControllerPeer { |
HttpStreamFactoryImpl::JobController* job_controller) { |
return job_controller->main_job_is_blocked_; |
} |
- static bool main_job_is_resumed( |
- HttpStreamFactoryImpl::JobController* job_controller) { |
- return job_controller->main_job_is_resumed_; |
- } |
}; |
class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
public: |
HttpStreamFactoryImplJobControllerTest() |
: session_deps_(ProxyService::CreateDirect()), |
- random_generator_(0), |
- client_maker_(HttpNetworkSession::Params().quic_supported_versions[0], |
- 0, |
- &clock_, |
- kServerHostname, |
- Perspective::IS_CLIENT), |
use_alternative_proxy_(false), |
is_preconnect_(false), |
enable_ip_based_pooling_(true), |
@@ -211,27 +166,18 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); |
session_deps_.proxy_delegate = std::move(test_proxy_delegate); |
- if (quic_data_) |
- quic_data_->AddSocketDataToFactory(session_deps_.socket_factory.get()); |
- if (tcp_data_) |
- session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get()); |
- |
if (use_alternative_proxy_) { |
std::unique_ptr<ProxyService> proxy_service = |
ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443"); |
session_deps_.proxy_service = std::move(proxy_service); |
} |
- HttpNetworkSession::Params params = |
- SpdySessionDependencies::CreateSessionParams(&session_deps_); |
- params.quic_crypto_client_stream_factory = &crypto_client_stream_factory_; |
- params.quic_random = &random_generator_; |
- session_ = base::MakeUnique<HttpNetworkSession>(params); |
+ session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
factory_ = |
static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
job_controller_ = new HttpStreamFactoryImpl::JobController( |
factory_, &request_delegate_, session_.get(), &job_factory_, |
request_info, is_preconnect_, enable_ip_based_pooling_, |
- enable_alternative_services_, SSLConfig(), SSLConfig()); |
+ enable_alternative_services_); |
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
} |
@@ -239,16 +185,7 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
return test_proxy_delegate_; |
} |
- ~HttpStreamFactoryImplJobControllerTest() override { |
- if (quic_data_) { |
- EXPECT_TRUE(quic_data_->AllReadDataConsumed()); |
- EXPECT_TRUE(quic_data_->AllWriteDataConsumed()); |
- } |
- if (tcp_data_) { |
- EXPECT_TRUE(tcp_data_->AllReadDataConsumed()); |
- EXPECT_TRUE(tcp_data_->AllWriteDataConsumed()); |
- } |
- } |
+ ~HttpStreamFactoryImplJobControllerTest() override {} |
void SetAlternativeService(const HttpRequestInfo& request_info, |
AlternativeService alternative_service) { |
@@ -277,274 +214,29 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
HttpStreamFactoryImpl* factory_; |
HttpStreamFactoryImpl::JobController* job_controller_; |
std::unique_ptr<HttpStreamFactoryImpl::Request> request_; |
- std::unique_ptr<SequencedSocketData> tcp_data_; |
- std::unique_ptr<test::MockQuicData> quic_data_; |
- MockCryptoClientStreamFactory crypto_client_stream_factory_; |
- MockClock clock_; |
- test::MockRandom random_generator_; |
- test::QuicTestPacketMaker client_maker_; |
- protected: |
+ private: |
bool use_alternative_proxy_; |
bool is_preconnect_; |
bool enable_ip_based_pooling_; |
bool enable_alternative_services_; |
- private: |
// Not owned by |this|. |
TestProxyDelegate* test_proxy_delegate_; |
DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); |
}; |
-TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) { |
- ProxyConfig proxy_config; |
- proxy_config.set_pac_url(GURL("http://fooproxyurl")); |
- proxy_config.set_pac_mandatory(true); |
- MockAsyncProxyResolver resolver; |
- session_deps_.proxy_service.reset(new ProxyService( |
- base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
- base::WrapUnique(new FailingProxyResolverFactory), nullptr)); |
- HttpRequestInfo request_info; |
- request_info.method = "GET"; |
- request_info.url = GURL("http://www.google.com"); |
- |
- Initialize(request_info); |
- |
- EXPECT_CALL(request_delegate_, |
- OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _)) |
- .Times(1); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- |
- EXPECT_FALSE(job_controller_->main_job()); |
- EXPECT_FALSE(job_controller_->alternative_job()); |
- |
- // Make sure calling GetLoadState() when before job creation does not crash. |
- // Regression test for crbug.com/723920. |
- EXPECT_EQ(LOAD_STATE_IDLE, job_controller_->GetLoadState()); |
- |
- base::RunLoop().RunUntilIdle(); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
-} |
- |
-TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) { |
+TEST_F(HttpStreamFactoryImplJobControllerTest, |
+ OnStreamFailedWithNoAlternativeJob) { |
ProxyConfig proxy_config; |
- proxy_config.set_pac_url(GURL("http://fooproxyurl")); |
- proxy_config.set_pac_mandatory(true); |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
MockAsyncProxyResolverFactory* proxy_resolver_factory = |
new MockAsyncProxyResolverFactory(false); |
- MockAsyncProxyResolver resolver; |
session_deps_.proxy_service.reset( |
new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
base::WrapUnique(proxy_resolver_factory), nullptr)); |
- HttpRequestInfo request_info; |
- request_info.method = "GET"; |
- request_info.url = GURL("http://www.google.com"); |
- |
- Initialize(request_info); |
- |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- |
- EXPECT_FALSE(job_controller_->main_job()); |
- EXPECT_FALSE(job_controller_->alternative_job()); |
- |
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, |
- job_controller_->GetLoadState()); |
- |
- EXPECT_CALL(request_delegate_, |
- OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _)) |
- .Times(1); |
- proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( |
- ERR_FAILED, &resolver); |
- base::RunLoop().RunUntilIdle(); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
-} |
- |
-TEST_F(HttpStreamFactoryImplJobControllerTest, NoSupportedProxies) { |
- session_deps_.proxy_service = |
- ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443"); |
- session_deps_.enable_quic = false; |
- HttpRequestInfo request_info; |
- request_info.method = "GET"; |
- request_info.url = GURL("http://www.google.com"); |
- |
- Initialize(request_info); |
- |
- EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_NO_SUPPORTED_PROXIES, _)) |
- .Times(1); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- |
- EXPECT_FALSE(job_controller_->main_job()); |
- EXPECT_FALSE(job_controller_->alternative_job()); |
- |
- base::RunLoop().RunUntilIdle(); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
-} |
- |
-class JobControllerReconsiderProxyAfterErrorTest |
- : public HttpStreamFactoryImplJobControllerTest, |
- public ::testing::WithParamInterface<::testing::tuple<bool, int>> { |
- public: |
- void Initialize(std::unique_ptr<ProxyService> proxy_service, |
- std::unique_ptr<ProxyDelegate> proxy_delegate) { |
- session_deps_.proxy_delegate = std::move(proxy_delegate); |
- session_deps_.proxy_service = std::move(proxy_service); |
- HttpNetworkSession::Params params = |
- SpdySessionDependencies::CreateSessionParams(&session_deps_); |
- session_ = base::MakeUnique<HttpNetworkSession>(params); |
- factory_ = |
- static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
- } |
- |
- std::unique_ptr<HttpStreamRequest> CreateJobController( |
- const HttpRequestInfo& request_info) { |
- HttpStreamFactoryImpl::JobController* job_controller = |
- new HttpStreamFactoryImpl::JobController( |
- factory_, &request_delegate_, session_.get(), &default_job_factory_, |
- request_info, is_preconnect_, enable_ip_based_pooling_, |
- enable_alternative_services_, SSLConfig(), SSLConfig()); |
- HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
- return job_controller->Start( |
- &request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- } |
- |
- private: |
- // Use real Jobs so that Job::Resume() is not mocked out. When main job is |
- // resumed it will use mock socket data. |
- HttpStreamFactoryImpl::JobFactory default_job_factory_; |
-}; |
- |
-INSTANTIATE_TEST_CASE_P( |
- /* no prefix */, |
- JobControllerReconsiderProxyAfterErrorTest, |
- ::testing::Combine(::testing::Bool(), |
- testing::ValuesIn(proxy_test_mock_errors))); |
- |
-TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) { |
- const bool set_alternative_proxy_server = ::testing::get<0>(GetParam()); |
- const int mock_error = ::testing::get<1>(GetParam()); |
- std::unique_ptr<ProxyService> proxy_service = |
- ProxyService::CreateFixedFromPacResult( |
- "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT"); |
- std::unique_ptr<TestProxyDelegate> test_proxy_delegate = |
- base::MakeUnique<TestProxyDelegate>(); |
- TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get(); |
- |
- // Before starting the test, verify that there are no proxies marked as bad. |
- ASSERT_TRUE(proxy_service->proxy_retry_info().empty()) << mock_error; |
- |
- StaticSocketDataProvider socket_data_proxy_main_job; |
- socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error)); |
- session_deps_.socket_factory->AddSocketDataProvider( |
- &socket_data_proxy_main_job); |
- |
- StaticSocketDataProvider socket_data_proxy_alternate_job; |
- if (set_alternative_proxy_server) { |
- // Mock socket used by the QUIC job. |
- socket_data_proxy_alternate_job.set_connect_data( |
- MockConnect(ASYNC, mock_error)); |
- session_deps_.socket_factory->AddSocketDataProvider( |
- &socket_data_proxy_alternate_job); |
- test_proxy_delegate->set_alternative_proxy_server( |
- ProxyServer::FromPacString("QUIC badproxy:99")); |
- } |
- |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- |
- // When retrying the job using the second proxy (badFallback:98), |
- // alternative job must not be created. So, socket data for only the |
- // main job is needed. |
- StaticSocketDataProvider socket_data_proxy_main_job_2; |
- socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, mock_error)); |
- session_deps_.socket_factory->AddSocketDataProvider( |
- &socket_data_proxy_main_job_2); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
- // First request would use DIRECT, and succeed. |
- StaticSocketDataProvider socket_data_direct_first_request; |
- socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); |
- session_deps_.socket_factory->AddSocketDataProvider( |
- &socket_data_direct_first_request); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
- // Second request would use DIRECT, and succeed. |
- StaticSocketDataProvider socket_data_direct_second_request; |
- socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK)); |
- session_deps_.socket_factory->AddSocketDataProvider( |
- &socket_data_direct_second_request); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
- // Now request a stream. It should succeed using the DIRECT. |
- HttpRequestInfo request_info; |
- request_info.method = "GET"; |
- request_info.url = GURL("http://www.example.com"); |
- |
- Initialize(std::move(proxy_service), std::move(test_proxy_delegate)); |
- EXPECT_EQ(set_alternative_proxy_server, |
- test_proxy_delegate_raw->alternative_proxy_server().is_quic()); |
- |
- // Start two requests. The first request should consume data from |
- // |socket_data_proxy_main_job|, |
- // |socket_data_proxy_alternate_job| and |
- // |socket_data_direct_first_request|. The second request should consume |
- // data from |socket_data_direct_second_request|. |
- |
- for (size_t i = 0; i < 2; ++i) { |
- ProxyInfo used_proxy_info; |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .Times(1) |
- .WillOnce(DoAll(::testing::SaveArg<1>(&used_proxy_info), |
- Invoke(DeleteHttpStreamPointer))); |
- |
- std::unique_ptr<HttpStreamRequest> request = |
- CreateJobController(request_info); |
- |
- base::RunLoop().RunUntilIdle(); |
- // The proxy that failed should now be known to the proxy_service as |
- // bad. |
- const ProxyRetryInfoMap retry_info = |
- session_->proxy_service()->proxy_retry_info(); |
- EXPECT_EQ(2u, retry_info.size()) << mock_error; |
- EXPECT_NE(retry_info.end(), retry_info.find("https://badproxy:99")); |
- EXPECT_NE(retry_info.end(), retry_info.find("https://badfallbackproxy:98")); |
- |
- // Verify that request was fetched without proxy. |
- EXPECT_TRUE(used_proxy_info.is_direct()); |
- |
- // If alternative proxy server was specified, it should have been marked |
- // as invalid so that it is not used for subsequent requests. |
- EXPECT_FALSE( |
- test_proxy_delegate_raw->alternative_proxy_server().is_valid()); |
- |
- if (set_alternative_proxy_server) { |
- // GetAlternativeProxy should be called only once for the first |
- // request. |
- EXPECT_EQ(1, |
- test_proxy_delegate_raw->get_alternative_proxy_invocations()); |
- } else { |
- // Alternative proxy server job is never started. So, ProxyDelegate is |
- // queried once per request. |
- EXPECT_EQ(2, |
- test_proxy_delegate_raw->get_alternative_proxy_invocations()); |
- } |
- } |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
-} |
- |
-TEST_F(HttpStreamFactoryImplJobControllerTest, |
- OnStreamFailedWithNoAlternativeJob) { |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -552,54 +244,64 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
Initialize(request_info); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
- EXPECT_FALSE(job_controller_->alternative_job()); |
// There's no other alternative job. Thus when stream failed, it should |
// notify Request of the stream failure. |
EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
+ SSLConfig()); |
} |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
OnStreamReadyWithNoAlternativeJob) { |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
- |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("http://www.google.com"); |
Initialize(request_info); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
// There's no other alternative job. Thus when a stream is ready, it should |
// notify Request. |
- EXPECT_TRUE(job_controller_->main_job()); |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
} |
// Test we cancel Jobs correctly when the Request is explicitly canceled |
// before any Job is bound to Request. |
TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
- // Use COLD_START to make the alt job pending. |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, OK); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset(new ProxyService( |
+ base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
+ |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -609,9 +311,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
@@ -624,10 +327,14 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
} |
TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddConnect(ASYNC, ERR_FAILED); |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -638,32 +345,40 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
+ // We have the main job with unknown status when the alternative job is failed |
+ // thus should not notify Request of the alternative job's failure. But should |
+ // notify the main job to mark the alternative job failed. |
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
+ job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
+ SSLConfig()); |
+ EXPECT_TRUE(!job_controller_->alternative_job()); |
+ EXPECT_TRUE(job_controller_->main_job()); |
+ |
// The failure of second Job should be reported to Request as there's no more |
// pending Job to serve the Request. |
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
+ SSLConfig()); |
VerifyBrokenAlternateProtocolMapping(request_info, false); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
AltJobFailsAfterMainJobSucceeds) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(ASYNC, ERR_FAILED); |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(SYNCHRONOUS, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -674,22 +389,29 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
// Main job succeeds, starts serving Request and it should report status |
// to Request. The alternative job will mark the main job complete and gets |
// orphaned. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
+ |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
+ |
// JobController shouldn't report the status of second job as request |
// is already successfully served. |
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
- |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
+ SSLConfig()); |
VerifyBrokenAlternateProtocolMapping(request_info, true); |
// Reset the request as it's been successfully served. |
@@ -702,10 +424,13 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
// Regression test for crbug.com/678768. |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
AltJobSucceedsMainJobBlockedControllerDestroyed) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr)); |
- quic_data_->AddRead(ASYNC, OK); |
- |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -715,18 +440,21 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
url::SchemeHostPort server(request_info.url); |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
- // |alternative_job| succeeds and should report status to |request_delegate_|. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
+ // |alternative_job| succeeds and should report status to Request. |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.alternative_job()->SetStream(http_stream); |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
- |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
EXPECT_FALSE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
@@ -739,60 +467,17 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
-TEST_F(HttpStreamFactoryImplJobControllerTest, |
- SpdySessionKeyHasOriginHostPortPair) { |
- session_deps_.enable_http2_alternative_service = true; |
- |
- const char origin_host[] = "www.example.org"; |
- const uint16_t origin_port = 443; |
- const char alternative_host[] = "mail.example.org"; |
- const uint16_t alternative_port = 123; |
- |
- HttpRequestInfo request_info; |
- request_info.method = "GET"; |
- request_info.url = |
- GURL(base::StringPrintf("https://%s:%u", origin_host, origin_port)); |
- Initialize(request_info); |
- |
- url::SchemeHostPort server(request_info.url); |
- AlternativeService alternative_service(kProtoHTTP2, alternative_host, |
- alternative_port); |
- SetAlternativeService(request_info, alternative_service); |
- |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- |
- HostPortPair main_host_port_pair = |
- HttpStreamFactoryImplJobPeer::GetSpdySessionKey( |
- job_controller_->main_job()) |
- .host_port_pair(); |
- EXPECT_EQ(origin_host, main_host_port_pair.host()); |
- EXPECT_EQ(origin_port, main_host_port_pair.port()); |
- |
- HostPortPair alternative_host_port_pair = |
- HttpStreamFactoryImplJobPeer::GetSpdySessionKey( |
- job_controller_->alternative_job()) |
- .host_port_pair(); |
- EXPECT_EQ(origin_host, alternative_host_port_pair.host()); |
- EXPECT_EQ(origin_port, alternative_host_port_pair.port()); |
-} |
- |
// Tests that if an orphaned job completes after |request_| is gone, |
// JobController will be cleaned up. |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
OrphanedJobCompletesControllerDestroyed) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
- // Use cold start and complete alt job manually. |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -802,21 +487,35 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
url::SchemeHostPort server(request_info.url); |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ // Hack to use different URL for the main job to help differentiate the proxy |
+ // requests. |
+ job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
- // main job should not be blocked because alt job returned ERR_IO_PENDING. |
- EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
- |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
// Complete main job now. |
- base::RunLoop().RunUntilIdle(); |
+ MockAsyncProxyResolver resolver; |
+ proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( |
+ net::OK, &resolver); |
+ int main_job_request_id = |
+ resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; |
+ |
+ resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( |
+ "result1:80"); |
+ resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
+ |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
+ .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
// Invoke OnRequestComplete() which should not delete |job_controller_| from |
// |factory_| because alt job is yet to finish. |
request_.reset(); |
@@ -825,9 +524,11 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
EXPECT_TRUE(job_controller_->alternative_job()); |
// Make |alternative_job| succeed. |
- HttpStream* http_stream = |
+ resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); |
+ resolver.pending_jobs()[0]->CompleteNow(net::OK); |
+ HttpStream* http_stream2 = |
new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
- job_factory_.alternative_job()->SetStream(http_stream); |
+ job_factory_.alternative_job()->SetStream(http_stream2); |
// This should not call request_delegate_::OnStreamReady. |
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
// Make sure that controller does not leak. |
@@ -836,16 +537,14 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
AltJobSucceedsAfterMainJobFailed) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
- // Use cold start and complete alt job manually. |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- |
- // One failed TCP connect. |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED)); |
- |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -856,44 +555,41 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- // |main_job| fails but should not report status to Request. |
- EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
- |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
- base::RunLoop().RunUntilIdle(); |
+ // |main_job| fails but should not report status to Request. |
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
- // Make |alternative_job| succeed. |
+ job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
+ SSLConfig()); |
+ |
+ // |alternative_job| succeeds and should report status to Request. |
HttpStream* http_stream = |
new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.alternative_job()->SetStream(http_stream); |
EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
- |
- job_factory_.alternative_job()->SetStream(http_stream); |
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
- |
- // |alternative_job| succeeds and should report status to Request. |
VerifyBrokenAlternateProtocolMapping(request_info, false); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
MainJobSucceedsAfterAltJobFailed) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
base::HistogramTester histogram_tester; |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -904,40 +600,47 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
// |alternative_job| fails but should not report status to Request. |
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
+ |
+ job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
+ SSLConfig()); |
+ |
// |main_job| succeeds and should report status to Request. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
- base::RunLoop().RunUntilIdle(); |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
+ .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
// Verify that the alternate protocol is marked as broken. |
VerifyBrokenAlternateProtocolMapping(request_info, true); |
histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, |
1); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
// Verifies that if the alternative job fails due to a connection change event, |
// then the alternative service is not marked as broken. |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
MainJobSucceedsAfterConnectionChanged) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddConnect(SYNCHRONOUS, ERR_NETWORK_CHANGED); |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
base::HistogramTester histogram_tester; |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -948,38 +651,45 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
// |alternative_job| fails but should not report status to Request. |
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
+ |
+ job_controller_->OnStreamFailed(job_factory_.alternative_job(), |
+ ERR_NETWORK_CHANGED, SSLConfig()); |
+ |
// |main_job| succeeds and should report status to Request. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
+ |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
// Verify that the alternate protocol is not marked as broken. |
VerifyBrokenAlternateProtocolMapping(request_info, false); |
histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", |
-ERR_NETWORK_CHANGED, 1); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
// Regression test for crbug/621069. |
// Get load state after main job fails and before alternative job succeeds. |
TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
- // Use COLD_START to complete alt job manually. |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset(new ProxyService( |
+ base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -990,9 +700,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
@@ -1000,7 +711,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
// The alternative job will mark the main job complete. |
EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
+ SSLConfig()); |
// Controller should use alternative job to get load state. |
job_controller_->GetLoadState(); |
@@ -1013,21 +725,18 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
} |
-TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) { |
- // Use COLD_START to stall alt job. |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
+TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { |
+ // Use failing ProxyResolverFactory which is unable to create ProxyResolver |
+ // to stall the alternative job and report to controller to maybe resume the |
+ // main job. |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ proxy_config.set_pac_mandatory(true); |
+ session_deps_.proxy_service.reset(new ProxyService( |
+ base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(new FailingProxyResolverFactory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
@@ -1038,16 +747,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
- // Alt job is stalled and main job should complete successfully. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .WillOnce(Invoke(DeleteHttpStreamPointer)); |
- |
+ // Wait until OnStreamFailedCallback is executed on the alternative job. |
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); |
base::RunLoop().RunUntilIdle(); |
} |
@@ -1064,9 +772,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 101); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_factory_.main_job()->is_waiting()); |
@@ -1075,6 +784,135 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { |
base::RunLoop().RunUntilIdle(); |
} |
+TEST_F(HttpStreamFactoryImplJobControllerTest, |
+ NoAvailableSpdySessionToResumeMainJob) { |
+ // Test the alternative job is not resumed when the alternative job is |
+ // IO_PENDING for proxy resolution. Once all the proxy resolution succeeds, |
+ // the latter part of this test tests controller resumes the main job |
+ // when there's no SPDY session for the alternative job. |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
+ |
+ HangingResolver* host_resolver = new HangingResolver(); |
+ session_deps_.host_resolver.reset(host_resolver); |
+ session_deps_.host_resolver->set_synchronous_mode(false); |
+ |
+ HttpRequestInfo request_info; |
+ request_info.method = "GET"; |
+ request_info.url = GURL("https://www.google.com"); |
+ |
+ Initialize(request_info); |
+ |
+ // Set a SPDY alternative service for the server. |
+ url::SchemeHostPort server(request_info.url); |
+ AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
+ SetAlternativeService(request_info, alternative_service); |
+ // Hack to use different URL for the main job to help differentiate the proxy |
+ // requests. |
+ job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); |
+ |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
+ // Both jobs should be created but stalled as proxy resolution not completed. |
+ EXPECT_TRUE(job_controller_->main_job()); |
+ EXPECT_TRUE(job_controller_->alternative_job()); |
+ |
+ MockAsyncProxyResolver resolver; |
+ proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( |
+ net::OK, &resolver); |
+ |
+ // Resolve proxy for the main job which then proceed to wait for the |
+ // alternative job which is IO_PENDING. |
+ int main_job_request_id = |
+ resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; |
+ |
+ resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( |
+ "result1:80"); |
+ resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); |
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
+ |
+ // Resolve proxy for the alternative job to proceed to create a connection. |
+ // Use hanging HostResolver to fail creation of a SPDY session for the |
+ // alternative job. The alternative job will be IO_PENDING thus should resume |
+ // the main job. |
+ resolver.pending_jobs()[0]->CompleteNow(net::OK); |
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+} |
+ |
+TEST_F(HttpStreamFactoryImplJobControllerTest, |
+ NoAvailableQuicSessionToResumeMainJob) { |
+ // Use failing HostResolver which is unable to resolve the host name for QUIC. |
+ // No QUIC session is created and thus should resume the main job. |
+ FailingHostResolver* host_resolver = new FailingHostResolver(); |
+ session_deps_.host_resolver.reset(host_resolver); |
+ |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
+ |
+ HttpRequestInfo request_info; |
+ request_info.method = "GET"; |
+ request_info.url = GURL("https://www.google.com"); |
+ |
+ Initialize(request_info); |
+ url::SchemeHostPort server(request_info.url); |
+ AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
+ SetAlternativeService(request_info, alternative_service); |
+ // Hack to use different URL for the main job to help differentiate the proxy |
+ // requests. |
+ job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); |
+ |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
+ EXPECT_TRUE(job_controller_->main_job()); |
+ EXPECT_TRUE(job_controller_->alternative_job()); |
+ |
+ MockAsyncProxyResolver resolver; |
+ proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( |
+ net::OK, &resolver); |
+ |
+ // Resolve proxy for the main job which then proceed to wait for the |
+ // alternative job which is IO_PENDING. |
+ int main_job_request_id = |
+ resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; |
+ |
+ resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( |
+ "result1:80"); |
+ resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); |
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
+ |
+ // Resolve proxy for the alternative job to proceed to create a connection. |
+ // Use failing HostResolver to fail creation of a QUIC session for the |
+ // alternative job. The alternative job will thus resume the main job. |
+ resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); |
+ resolver.pending_jobs()[0]->CompleteNow(net::OK); |
+ |
+ // Wait until OnStreamFailedCallback is executed on the alternative job. |
+ // Request shouldn't be notified as the main job is still pending status. |
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+} |
+ |
TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
auto failing_resolver = base::MakeUnique<MockHostResolver>(); |
@@ -1096,13 +934,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
session_->http_server_properties()->SetServerNetworkStats( |
url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
+ // Set a SPDY alternative service for the server. |
url::SchemeHostPort server(request_info.url); |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
@@ -1167,9 +1007,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) { |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
@@ -1226,9 +1067,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
// The alternative job stalls as host resolution hangs when creating the QUIC |
// request and controller should resume the main job with delay. |
// OnStreamFailed should resume the main job immediately. |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
@@ -1271,9 +1113,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { |
Initialize(request_info); |
EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
EXPECT_FALSE(job_controller_->alternative_job()); |
@@ -1297,9 +1140,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { |
Initialize(request_info); |
EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
EXPECT_FALSE(job_controller_->alternative_job()); |
@@ -1339,22 +1183,30 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
session_->http_server_properties()->SetServerNetworkStats( |
url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
- // The main job is unblocked but is resumed one message loop iteration later. |
- EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
- EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); |
+ EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
+ |
+ // Alternative proxy server job will start in the next message loop. |
+ EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
+ |
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
+ // Run tasks with no remaining delay, this will start the alternative proxy |
+ // server job. The alternative proxy server job stalls when connecting to the |
+ // alternative proxy server, and should schedule a task to resume the main job |
+ // after delay. That task will be queued. |
+ test_task_runner->RunUntilIdle(); |
EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
// Move forward the delay and verify the main job is resumed. |
EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
- EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_)); |
test_task_runner->RunUntilIdle(); |
EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
@@ -1369,15 +1221,13 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
EXPECT_FALSE(job_controller_->alternative_job()); |
} |
-// Verifies that if the alternative proxy server job fails immediately, the |
+// Verifies that the alternative proxy server job fails immediately, and the |
// main job is not blocked. |
TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED); |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
+ base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
+ // Using failing resolver will cause the alternative job to fail. |
+ FailingHostResolver* resolver = new FailingHostResolver(); |
+ session_deps_.host_resolver.reset(resolver); |
UseAlternativeProxy(); |
@@ -1395,41 +1245,38 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
session_->http_server_properties()->SetServerNetworkStats( |
url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
- EXPECT_TRUE(job_controller_->main_job()); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
- base::RunLoop().RunUntilIdle(); |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); |
- EXPECT_FALSE(job_controller_->alternative_job()); |
- EXPECT_TRUE(job_controller_->main_job()); |
+ // Since the alternative proxy server job is started in the next message loop, |
+ // the main job would remain blocked until the alternative proxy starts, and |
+ // fails. |
+ EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
+ |
+ // Run tasks with no remaining delay. |
+ test_task_runner->RunUntilIdle(); |
- // The alternative proxy server should be marked as bad. |
- EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
+ EXPECT_FALSE(job_controller_->alternative_job()); |
+ EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
+ // Since the main job did not complete successfully, the alternative proxy |
+ // server should not be marked as bad. |
+ EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
- request_.reset(); |
- EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
+ EXPECT_FALSE(test_task_runner->HasPendingTask()); |
} |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
AlternativeProxyServerJobFailsAfterMainJobSucceeds) { |
base::HistogramTester histogram_tester; |
- // Use COLD_START to make the alt job pending. |
- crypto_client_stream_factory_.set_handshake_mode( |
- MockCryptoClientStream::COLD_START); |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
- |
UseAlternativeProxy(); |
HttpRequestInfo request_info; |
@@ -1439,22 +1286,23 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
url::SchemeHostPort server(request_info.url); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_TRUE(job_controller_->alternative_job()); |
// Main job succeeds, starts serving Request and it should report status |
// to Request. The alternative job will mark the main job complete and gets |
// orphaned. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
- .WillOnce(Invoke(DeleteHttpStreamPointer)); |
- |
- base::RunLoop().RunUntilIdle(); |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
- EXPECT_TRUE(job_controller_->main_job()); |
- EXPECT_TRUE(job_controller_->alternative_job()); |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
+ .WillOnce(Invoke(DeleteHttpStreamPointer)); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
// JobController shouldn't report the status of alternative server job as |
// request is already successfully served. |
@@ -1474,8 +1322,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
// When preconnect to a H2 supported server, only 1 connection is opened. |
TEST_F(HttpStreamFactoryImplJobControllerTest, |
PreconnectMultipleStreamsToH2Server) { |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
+ MockRead reads[] = {MockRead(ASYNC, OK)}; |
+ SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
+ session_deps_.socket_factory->AddSocketDataProvider(&data); |
+ |
SetPreconnect(); |
HttpRequestInfo request_info; |
@@ -1488,7 +1338,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
// Sets server support Http/2. |
session_->http_server_properties()->SetSupportsSpdy(server, true); |
- job_controller_->Preconnect(/*num_streams=*/5); |
+ job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), |
+ SSLConfig()); |
// Only one job is started. |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_FALSE(job_controller_->alternative_job()); |
@@ -1513,17 +1364,15 @@ TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
DisableIPBasedPoolingAndAlternativeServices) { |
const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); |
const bool enable_alternative_services = ::testing::get<1>(GetParam()); |
- if (enable_alternative_services) { |
- quic_data_ = base::MakeUnique<test::MockQuicData>(); |
- quic_data_->AddConnect(SYNCHRONOUS, OK); |
- quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr)); |
- quic_data_->AddRead(ASYNC, OK); |
- } |
- tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
- tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
- auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
- session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
+ ProxyConfig proxy_config; |
+ proxy_config.set_auto_detect(true); |
+ // Use asynchronous proxy resolver. |
+ MockAsyncProxyResolverFactory* proxy_resolver_factory = |
+ new MockAsyncProxyResolverFactory(false); |
+ session_deps_.proxy_service.reset( |
+ new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
+ base::WrapUnique(proxy_resolver_factory), nullptr)); |
HttpRequestInfo request_info; |
request_info.method = "GET"; |
request_info.url = GURL("https://www.google.com"); |
@@ -1539,9 +1388,10 @@ TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
SetAlternativeService(request_info, alternative_service); |
- request_ = |
- job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
+ request_.reset( |
+ job_controller_->Start(request_info, &request_delegate_, nullptr, |
+ NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
+ DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
EXPECT_TRUE(job_controller_->main_job()); |
if (enable_alternative_services) { |
EXPECT_TRUE(job_controller_->alternative_job()); |
@@ -1550,9 +1400,13 @@ TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
} |
// |main_job| succeeds and should report status to Request. |
- EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
+ HttpStream* http_stream = |
+ new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
+ job_factory_.main_job()->SetStream(http_stream); |
+ |
+ EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
.WillOnce(Invoke(DeleteHttpStreamPointer)); |
- base::RunLoop().RunUntilIdle(); |
+ job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
} |
class HttpStreamFactoryImplJobControllerPreconnectTest |
@@ -1578,13 +1432,14 @@ class HttpStreamFactoryImplJobControllerPreconnectTest |
factory_, &request_delegate_, session_.get(), &job_factory_, |
request_info_, /* is_preconnect = */ true, |
/* enable_ip_based_pooling = */ true, |
- /* enable_alternative_services = */ true, SSLConfig(), SSLConfig()); |
+ /* enable_alternative_services = */ true); |
HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
} |
protected: |
void Preconnect(int num_streams) { |
- job_controller_->Preconnect(num_streams); |
+ job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), |
+ SSLConfig()); |
// Only one job is started. |
EXPECT_TRUE(job_controller_->main_job()); |
EXPECT_FALSE(job_controller_->alternative_job()); |