Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(520)

Unified Diff: net/http/http_stream_factory_impl_job_controller_unittest.cc

Issue 2895263003: Revert CLs landed in HttpStreamFactoryImpl to track down a crasher (Closed)
Patch Set: Revert "Fix SpdySessionKey for HTTP/2 alternative Jobs." Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());

Powered by Google App Engine
This is Rietveld 408576698