Chromium Code Reviews| 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 422b2453fde4e9d3eed2c36175a6421fc58a9a58..49174d3c88d3d823cf46d0e1bfe7cf3c7a4c8f37 100644 |
| --- a/net/http/http_stream_factory_impl_job_controller_unittest.cc |
| +++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc |
| @@ -23,7 +23,11 @@ |
| #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/socket/socket_test_util.h" |
| #include "net/spdy/chromium/spdy_test_util_common.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| @@ -37,6 +41,8 @@ namespace net { |
| namespace { |
| +const char kServerHostname[] = "www.example.com"; |
| + |
| void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| HttpStream* stream) { |
| @@ -89,6 +95,59 @@ class HangingResolver : public MockHostResolverBase { |
| } |
| }; |
| +// A mock QuicStreamRequest that always succeeds. |
| +class MockQuicStreamRequest : public QuicStreamRequest { |
| + public: |
| + MockQuicStreamRequest(int net_error) |
| + : QuicStreamRequest(nullptr, nullptr), net_error_(net_error) {} |
| + ~MockQuicStreamRequest() {} |
| + |
| + int Request(const HostPortPair& destination, |
| + PrivacyMode privacy_mode, |
| + int cert_verify_flags, |
| + const GURL& url, |
| + QuicStringPiece method, |
| + const NetLogWithSource& net_log, |
| + const CompletionCallback& callback) override { |
| + return net_error_; |
| + } |
| + |
| + std::unique_ptr<HttpStream> CreateStream() override { |
| + if (net_error_ != OK) { |
| + NOTREACHED(); |
| + return nullptr; |
| + } |
| + return base::MakeUnique<HttpBasicStream>( |
| + base::MakeUnique<ClientSocketHandle>(), false, false); |
| + } |
| + |
| + std::unique_ptr<BidirectionalStreamImpl> CreateBidirectionalStreamImpl() |
| + override { |
| + NOTREACHED(); |
| + return nullptr; |
| + } |
| + |
| + private: |
| + int net_error_; |
| +}; |
| + |
| +// A mock QuicStreamRequest that always succeeds. |
| +class MockQuicStreamRequestFactory : public QuicStreamRequestFactory { |
| + public: |
| + MockQuicStreamRequestFactory(int net_error) |
| + : QuicStreamRequestFactory(), net_error_(net_error) {} |
| + ~MockQuicStreamRequestFactory() {} |
| + |
| + std::unique_ptr<QuicStreamRequest> CreateRequest( |
| + QuicStreamFactory* factory, |
| + HttpServerProperties* http_server_properties) override { |
| + return base::MakeUnique<MockQuicStreamRequest>(net_error_); |
| + } |
| + |
| + private: |
| + int net_error_; |
| +}; |
| + |
| // A mock HttpServerProperties that always returns false for IsInitialized(). |
| class MockHttpServerProperties : public HttpServerPropertiesImpl { |
| public: |
| @@ -127,6 +186,11 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
| public: |
| HttpStreamFactoryImplJobControllerTest() |
| : session_deps_(ProxyService::CreateDirect()), |
| + client_maker_(kSupportedQuicVersions[0], |
| + 0, |
| + &clock_, |
| + kServerHostname, |
| + Perspective::IS_CLIENT), |
| use_alternative_proxy_(false), |
| is_preconnect_(false), |
| enable_ip_based_pooling_(true), |
| @@ -166,18 +230,24 @@ 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 (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); |
| } |
| - session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
| + HttpNetworkSession::Params params = |
| + SpdySessionDependencies::CreateSessionParams(&session_deps_); |
| + params.quic_crypto_client_stream_factory = &crypto_client_stream_factory_; |
| + session_ = base::MakeUnique<HttpNetworkSession>(params); |
| 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_); |
| + enable_alternative_services_, SSLConfig(), SSLConfig()); |
| HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
| } |
| @@ -185,7 +255,12 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
| return test_proxy_delegate_; |
| } |
| - ~HttpStreamFactoryImplJobControllerTest() override {} |
| + ~HttpStreamFactoryImplJobControllerTest() override { |
| + if (tcp_data_) { |
| + EXPECT_TRUE(tcp_data_->AllReadDataConsumed()); |
| + EXPECT_TRUE(tcp_data_->AllWriteDataConsumed()); |
| + } |
| + } |
| void SetAlternativeService(const HttpRequestInfo& request_info, |
| AlternativeService alternative_service) { |
| @@ -214,6 +289,10 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
| HttpStreamFactoryImpl* factory_; |
| HttpStreamFactoryImpl::JobController* job_controller_; |
| std::unique_ptr<HttpStreamFactoryImpl::Request> request_; |
| + std::unique_ptr<SequencedSocketData> tcp_data_; |
| + MockCryptoClientStreamFactory crypto_client_stream_factory_; |
| + MockClock clock_; |
| + test::QuicTestPacketMaker client_maker_; |
| private: |
| bool use_alternative_proxy_; |
| @@ -227,16 +306,72 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
| DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); |
| }; |
| -TEST_F(HttpStreamFactoryImplJobControllerTest, |
| - OnStreamFailedWithNoAlternativeJob) { |
| +TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) { |
| + ProxyConfig proxy_config; |
| + proxy_config.set_pac_url(GURL("http://www.example.com")); |
| + 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_.reset( |
| + 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_)); |
| +} |
| + |
| +TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) { |
| ProxyConfig proxy_config; |
| - proxy_config.set_auto_detect(true); |
| - // Use asynchronous proxy resolver. |
| + proxy_config.set_pac_url(GURL("http://www.example.com")); |
| + proxy_config.set_pac_mandatory(true); |
| 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_.reset( |
| + 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_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, |
| + 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"; |
| @@ -245,29 +380,23 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| Initialize(request_info); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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); |
| - job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
| - SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| } |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| OnStreamReadyWithNoAlternativeJob) { |
| - 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)); |
| + tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| + tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| + |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| request_info.url = GURL("http://www.google.com"); |
| @@ -275,33 +404,24 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| Initialize(request_info); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| // There's no other alternative job. Thus when a stream is ready, it should |
| // notify Request. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.main_job()->SetStream(http_stream); |
| + EXPECT_TRUE(job_controller_->main_job()); |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| - job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| } |
| // Test we cancel Jobs correctly when the Request is explicitly canceled |
| // before any Job is bound to Request. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
| - 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)); |
| - |
| + // One TCP connect. |
| + tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| + tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| request_info.url = GURL("https://www.google.com"); |
| @@ -311,10 +431,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(OK)); |
| + */ |
| + |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -327,14 +452,9 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
| } |
| TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
| - 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)); |
| + // One TCP connect and one UDP connect. |
| + 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"; |
| @@ -345,40 +465,34 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); |
| + */ |
| + |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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); |
| - job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
| - SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| VerifyBrokenAlternateProtocolMapping(request_info, false); |
| + request_.reset(); |
| + EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| } |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| AltJobFailsAfterMainJobSucceeds) { |
| - 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)); |
| + // One TCP connect. |
| + 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()); |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| @@ -388,30 +502,28 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| url::SchemeHostPort server(request_info.url); |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); |
| + */ |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.main_job()->SetStream(http_stream); |
| - |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .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); |
| - job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
| - SSLConfig()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| VerifyBrokenAlternateProtocolMapping(request_info, true); |
| // Reset the request as it's been successfully served. |
| @@ -424,37 +536,33 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // Regression test for crbug.com/678768. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| AltJobSucceedsMainJobBlockedControllerDestroyed) { |
| - 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"); |
| Initialize(request_info); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(OK)); |
| + */ |
| + |
| url::SchemeHostPort server(request_info.url); |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.alternative_job()->SetStream(http_stream); |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + // |alternative_job| succeeds and should report status to |request_delegate_|. |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| - job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| EXPECT_FALSE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -471,51 +579,43 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // JobController will be cleaned up. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| OrphanedJobCompletesControllerDestroyed) { |
| - 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)); |
| + // One TCP connect. |
| + 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()); |
| + |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| request_info.url = GURL("https://www.google.com"); |
| Initialize(request_info); |
| + // Make QuicStreamRequest complete asynchonously. |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
| + */ |
| + |
| 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())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| - EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| - |
| - // Complete main job now. |
| - 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; |
| + // main job should not be blocked because alt job returned ERR_IO_PENDING. |
| + EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| - resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( |
| - "result1:80"); |
| - resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); |
| + 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); |
| + // Complete main job now. |
| + base::RunLoop().RunUntilIdle(); |
| - 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(); |
| @@ -524,11 +624,9 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| // Make |alternative_job| succeed. |
| - resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); |
| - resolver.pending_jobs()[0]->CompleteNow(net::OK); |
| - HttpStream* http_stream2 = |
| + HttpStream* http_stream = |
| new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.alternative_job()->SetStream(http_stream2); |
| + job_factory_.alternative_job()->SetStream(http_stream); |
| // This should not call request_delegate_::OnStreamReady. |
| job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| // Make sure that controller does not leak. |
| @@ -537,14 +635,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| AltJobSucceedsAfterMainJobFailed) { |
| - 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)); |
| + // One failed TCP connect. |
| + tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| + tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED)); |
| + |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| request_info.url = GURL("https://www.google.com"); |
| @@ -555,41 +649,46 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| - 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()); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
| + */ |
| // |main_job| fails but should not report status to Request. |
| EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| - job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
| - SSLConfig()); |
| + request_.reset( |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| + EXPECT_TRUE(job_controller_->main_job()); |
| + EXPECT_TRUE(job_controller_->alternative_job()); |
| - // |alternative_job| succeeds and should report status to Request. |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Make |alternative_job| succeed. |
| 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); |
| } |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| MainJobSucceedsAfterAltJobFailed) { |
| + // One TCP connect. |
| + 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"); |
| @@ -599,28 +698,25 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| url::SchemeHostPort server(request_info.url); |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /* |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); |
| + */ |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.main_job()->SetStream(http_stream); |
| - |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| - job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
| + |
| + base::RunLoop().RunUntilIdle(); |
| // Verify that the alternate protocol is marked as broken. |
| VerifyBrokenAlternateProtocolMapping(request_info, true); |
| @@ -632,15 +728,13 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // then the alternative service is not marked as broken. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| MainJobSucceedsAfterConnectionChanged) { |
| + // One TCP connect. |
| + 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)); |
| session_deps_.quic_do_not_mark_as_broken_on_network_change = true; |
| HttpRequestInfo request_info; |
| @@ -652,27 +746,24 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_NETWORK_CHANGED)); |
| + */ |
| + |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 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. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.main_job()->SetStream(http_stream); |
| - |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| - job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| // Verify that the alternate protocol is not marked as broken. |
| VerifyBrokenAlternateProtocolMapping(request_info, false); |
| @@ -683,14 +774,9 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // Regression test for crbug/621069. |
| // Get load state after main job fails and before alternative job succeeds. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
| - 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)); |
| + // One failed TCP connect. |
| + 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"; |
| @@ -701,10 +787,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
| + */ |
| + |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -712,8 +803,7 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
| // The alternative job will mark the main job complete. |
| EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| - job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, |
| - SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| // Controller should use alternative job to get load state. |
| job_controller_->GetLoadState(); |
| @@ -728,16 +818,12 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
| job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| } |
| -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)); |
| +TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) { |
| + // One TCP connect. |
| + 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()); |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| @@ -747,16 +833,22 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { |
| url::SchemeHostPort server(request_info.url); |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
| + */ |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| - // Wait until OnStreamFailedCallback is executed on the alternative job. |
| - EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); |
| + // Alt job is stalled and main job should complete successfully. |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| + .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| + |
| base::RunLoop().RunUntilIdle(); |
| } |
| @@ -774,9 +866,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { |
| SetAlternativeService(request_info, alternative_service); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_factory_.main_job()->is_waiting()); |
| @@ -785,135 +876,6 @@ 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>(); |
| @@ -935,15 +897,13 @@ 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_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| @@ -1009,9 +969,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) { |
| SetAlternativeService(request_info, alternative_service); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| @@ -1069,9 +1028,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // request and controller should resume the main job with delay. |
| // OnStreamFailed should resume the main job immediately. |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| @@ -1115,9 +1073,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { |
| EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
| EXPECT_FALSE(job_controller_->alternative_job()); |
| @@ -1142,9 +1099,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { |
| EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
| EXPECT_FALSE(job_controller_->alternative_job()); |
| @@ -1161,12 +1117,6 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
| // Overrides the main thread's message loop with a mock tick clock so that we |
| // could verify the main job is resumed with appropriate delay. |
| base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| - |
| - auto failing_resolver = base::MakeUnique<MockHostResolver>(); |
| - failing_resolver->set_ondemand_mode(true); |
| - failing_resolver->rules()->AddSimulatedFailure("*myproxy.org"); |
| - session_deps_.host_resolver = std::move(failing_resolver); |
| - |
| UseAlternativeProxy(); |
| HttpRequestInfo request_info; |
| @@ -1174,6 +1124,12 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
| request_info.url = GURL("http://mail.example.org/"); |
| Initialize(request_info); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
| + */ |
| + |
| EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| // Enable delayed TCP and set time delay for waiting job. |
| @@ -1185,27 +1141,20 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
| url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| 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); |
| + // Move forward the delay and verify the main job is resumed. |
| + EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| // 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_)); |
| @@ -1214,22 +1163,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
| EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| - // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can |
| - // be cleaned up. |
| - session_deps_.host_resolver->ResolveAllPending(); |
| - EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| - test_task_runner->FastForwardUntilNoTasksRemain(); |
| - EXPECT_FALSE(job_controller_->alternative_job()); |
| + // Resume() function is mocked, so we will still have main job around. |
| + EXPECT_TRUE(job_controller_->main_job()); |
| + EXPECT_TRUE(job_controller_->alternative_job()); |
| } |
| -// Verifies that the alternative proxy server job fails immediately, and the |
| +// Verifies that if the alternative proxy server job fails immediately, the |
| // main job is not blocked. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
| 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(); |
| HttpRequestInfo request_info; |
| @@ -1245,11 +1187,15 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
| stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); |
| session_->http_server_properties()->SetServerNetworkStats( |
| url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
| + /** |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); |
| + */ |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -1267,9 +1213,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
| 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()); |
| + // The alternative proxy server should be marked as bad. |
| + EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
| EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| } |
| @@ -1288,9 +1233,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| url::SchemeHostPort server(request_info.url); |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -1323,10 +1267,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // When preconnect to a H2 supported server, only 1 connection is opened. |
| TEST_F(HttpStreamFactoryImplJobControllerTest, |
| PreconnectMultipleStreamsToH2Server) { |
| - MockRead reads[] = {MockRead(ASYNC, OK)}; |
| - SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| - session_deps_.socket_factory->AddSocketDataProvider(&data); |
| - |
| + tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| + tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| SetPreconnect(); |
| HttpRequestInfo request_info; |
| @@ -1339,8 +1281,7 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, |
| // Sets server support Http/2. |
| session_->http_server_properties()->SetSupportsSpdy(server, true); |
| - job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), |
| - SSLConfig()); |
| + job_controller_->Preconnect(/*num_streams=*/5); |
| // Only one job is started. |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_FALSE(job_controller_->alternative_job()); |
| @@ -1366,33 +1307,46 @@ TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
| const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); |
| const bool enable_alternative_services = ::testing::get<1>(GetParam()); |
| - 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)); |
| + 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::MockQuicData mock_quic_data; |
| + if (enable_alternative_services) { |
| + mock_quic_data.AddWrite( |
| + client_maker_.MakeInitialSettingsPacket(1, nullptr)); |
|
xunjieli
2017/04/27 18:15:54
Ryan: so I tried your suggestion. However, I think
Ryan Hamilton
2017/04/27 21:52:47
The connection ID is generated "randomly" each tim
|
| + mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); |
| + mock_quic_data.AddRead(ASYNC, OK); |
| + mock_quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get()); |
| + } |
| + |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| request_info.url = GURL("https://www.google.com"); |
| if (!enable_ip_based_pooling) |
| DisableIPBasedPooling(); |
| - if (!enable_alternative_services) |
| + if (!enable_alternative_services) { |
| DisableAlternativeServices(); |
| + } |
| Initialize(request_info); |
| url::SchemeHostPort server(request_info.url); |
| AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| SetAlternativeService(request_info, alternative_service); |
| + /** |
| +if (enable_alternative_services) { |
| + // Mock out Quic request |
| + test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
| + session_->quic_stream_factory(), |
| + base::MakeUnique<MockQuicStreamRequestFactory>(OK)); |
| +} |
| +*/ |
| request_.reset( |
| - job_controller_->Start(request_info, &request_delegate_, nullptr, |
| - NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| - DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| + job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| EXPECT_TRUE(job_controller_->main_job()); |
| if (enable_alternative_services) { |
| EXPECT_TRUE(job_controller_->alternative_job()); |
| @@ -1401,13 +1355,9 @@ TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
| } |
| // |main_job| succeeds and should report status to Request. |
| - HttpStream* http_stream = |
| - new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| - job_factory_.main_job()->SetStream(http_stream); |
| - |
| - EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| - job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); |
| + base::RunLoop().RunUntilIdle(); |
| } |
| class HttpStreamFactoryImplJobControllerPreconnectTest |
| @@ -1433,14 +1383,13 @@ class HttpStreamFactoryImplJobControllerPreconnectTest |
| factory_, &request_delegate_, session_.get(), &job_factory_, |
| request_info_, /* is_preconnect = */ true, |
| /* enable_ip_based_pooling = */ true, |
| - /* enable_alternative_services = */ true); |
| + /* enable_alternative_services = */ true, SSLConfig(), SSLConfig()); |
| HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
| } |
| protected: |
| void Preconnect(int num_streams) { |
| - job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), |
| - SSLConfig()); |
| + job_controller_->Preconnect(num_streams); |
| // Only one job is started. |
| EXPECT_TRUE(job_controller_->main_job()); |
| EXPECT_FALSE(job_controller_->alternative_job()); |