summaryrefslogtreecommitdiff
path: root/chromium/net/http/http_stream_factory_job_controller_unittest.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:19:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:01:50 +0000
commit51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch)
tree835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/net/http/http_stream_factory_job_controller_unittest.cc
parent6036726eb981b6c4b42047513b9d3f4ac865daac (diff)
downloadqtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/net/http/http_stream_factory_job_controller_unittest.cc')
-rw-r--r--chromium/net/http/http_stream_factory_job_controller_unittest.cc392
1 files changed, 365 insertions, 27 deletions
diff --git a/chromium/net/http/http_stream_factory_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_job_controller_unittest.cc
index b2d4fa5a5d7..35a402f1cd0 100644
--- a/chromium/net/http/http_stream_factory_job_controller_unittest.cc
+++ b/chromium/net/http/http_stream_factory_job_controller_unittest.cc
@@ -165,6 +165,11 @@ class HttpStreamFactoryJobPeer {
std::unique_ptr<HttpStream> http_stream) {
job->stream_ = std::move(http_stream);
}
+
+ static void SetQuicConnectionFailedOnDefaultNetwork(
+ HttpStreamFactory::Job* job) {
+ job->quic_request_.OnConnectionFailedOnDefaultNetwork();
+ }
};
class JobControllerPeer {
@@ -187,6 +192,13 @@ class JobControllerPeer {
return job_controller->GetAlternativeServiceInfoFor(request_info, delegate,
stream_type);
}
+
+ static void SetAltJobFailedOnDefaultNetwork(
+ HttpStreamFactory::JobController* job_controller) {
+ DCHECK(job_controller->alternative_job() != nullptr);
+ HttpStreamFactoryJobPeer::SetQuicConnectionFailedOnDefaultNetwork(
+ job_controller->alternative_job_.get());
+ }
};
class HttpStreamFactoryJobControllerTest
@@ -226,13 +238,10 @@ class HttpStreamFactoryJobControllerTest
void Initialize(const HttpRequestInfo& request_info) {
ASSERT_FALSE(test_proxy_delegate_);
- auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
- test_proxy_delegate_ = test_proxy_delegate.get();
-
- test_proxy_delegate->set_alternative_proxy_server(
+ test_proxy_delegate_ = std::make_unique<TestProxyDelegate>();
+ test_proxy_delegate_->set_alternative_proxy_server(
ProxyServer::FromPacString("QUIC myproxy.org:443"));
- EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic());
- session_deps_.proxy_delegate = std::move(test_proxy_delegate);
+ EXPECT_TRUE(test_proxy_delegate_->alternative_proxy_server().is_quic());
if (quic_data_)
quic_data_->AddSocketDataToFactory(session_deps_.socket_factory.get());
@@ -246,6 +255,10 @@ class HttpStreamFactoryJobControllerTest
session_deps_.proxy_resolution_service =
std::move(proxy_resolution_service);
}
+
+ session_deps_.proxy_resolution_service->SetProxyDelegate(
+ test_proxy_delegate_.get());
+
session_deps_.net_log = net_log_.bound().net_log();
HttpNetworkSession::Params params =
SpdySessionDependencies::CreateSessionParams(&session_deps_);
@@ -268,7 +281,7 @@ class HttpStreamFactoryJobControllerTest
}
TestProxyDelegate* test_proxy_delegate() const {
- return test_proxy_delegate_;
+ return test_proxy_delegate_.get();
}
~HttpStreamFactoryJobControllerTest() override {
@@ -307,6 +320,21 @@ class HttpStreamFactoryJobControllerTest
alternative_service_info_vector[0].alternative_service()));
}
+ void TestAltJobSucceedsAfterMainJobFailed(
+ bool alt_job_retried_on_non_default_network);
+ void TestMainJobSucceedsAfterAltJobFailed(
+ bool alt_job_retried_on_non_default_network);
+ void TestAltJobSucceedsAfterMainJobSucceeded(
+ bool alt_job_retried_on_non_default_network);
+ void TestOnStreamFailedForBothJobs(
+ bool alt_job_retried_on_non_default_network);
+ void TestAltJobFailsAfterMainJobSucceeded(
+ bool alt_job_retried_on_non_default_network);
+ void TestMainJobSucceedsAfterAltJobSucceeded(
+ bool alt_job_retried_on_non_default_network);
+ void TestMainJobFailsAfterAltJobSucceeded(
+ bool alt_job_retried_on_non_default_network);
+
TestJobFactory job_factory_;
MockHttpStreamRequestDelegate request_delegate_;
SpdySessionDependencies session_deps_{ProxyResolutionService::CreateDirect()};
@@ -335,8 +363,7 @@ class HttpStreamFactoryJobControllerTest
bool enable_alternative_services_ = true;
private:
- // Not owned by |this|.
- TestProxyDelegate* test_proxy_delegate_ = nullptr;
+ std::unique_ptr<TestProxyDelegate> test_proxy_delegate_;
bool create_job_controller_ = true;
DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryJobControllerTest);
@@ -442,9 +469,7 @@ class JobControllerReconsiderProxyAfterErrorTest
public ::testing::WithParamInterface<::testing::tuple<bool, int>> {
public:
void Initialize(
- std::unique_ptr<ProxyResolutionService> proxy_resolution_service,
- std::unique_ptr<ProxyDelegate> proxy_delegate) {
- session_deps_.proxy_delegate = std::move(proxy_delegate);
+ std::unique_ptr<ProxyResolutionService> proxy_resolution_service) {
session_deps_.proxy_resolution_service =
std::move(proxy_resolution_service);
session_ = std::make_unique<HttpNetworkSession>(
@@ -551,8 +576,8 @@ TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) {
request_info.method = "GET";
request_info.url = GURL("http://www.example.com");
- Initialize(std::move(proxy_resolution_service),
- std::move(test_proxy_delegate));
+ proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get());
+ Initialize(std::move(proxy_resolution_service));
EXPECT_EQ(set_alternative_proxy_server,
test_proxy_delegate_raw->alternative_proxy_server().is_quic());
@@ -614,8 +639,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, ReconsiderErrMsgTooBig) {
request_info.method = "GET";
request_info.url = GURL("http://www.example.com");
- Initialize(std::move(proxy_resolution_service),
- std::make_unique<TestProxyDelegate>());
+ Initialize(std::move(proxy_resolution_service));
ProxyInfo used_proxy_info;
EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _))
@@ -662,8 +686,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest,
request_info.method = "GET";
request_info.url = GURL("http://www.example.com");
- Initialize(std::move(proxy_resolution_service),
- std::make_unique<TestProxyDelegate>());
+ Initialize(std::move(proxy_resolution_service));
ProxyInfo used_proxy_info;
EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_MSG_TOO_BIG, _, _))
@@ -698,8 +721,8 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest,
test_proxy_delegate->set_alternative_proxy_server(
ProxyServer::FromPacString("QUIC myproxy.org:443"));
- Initialize(std::move(proxy_resolution_service),
- std::move(test_proxy_delegate));
+ proxy_resolution_service->SetProxyDelegate(test_proxy_delegate.get());
+ Initialize(std::move(proxy_resolution_service));
// Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
@@ -858,7 +881,8 @@ TEST_F(HttpStreamFactoryJobControllerTest,
EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
}
-TEST_F(HttpStreamFactoryJobControllerTest, OnStreamFailedForBothJobs) {
+void HttpStreamFactoryJobControllerTest::TestOnStreamFailedForBothJobs(
+ bool alt_job_retried_on_non_default_network) {
quic_data_ = std::make_unique<MockQuicData>();
quic_data_->AddConnect(ASYNC, ERR_FAILED);
tcp_data_ = std::make_unique<SequencedSocketData>();
@@ -879,6 +903,12 @@ TEST_F(HttpStreamFactoryJobControllerTest, OnStreamFailedForBothJobs) {
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+
// 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);
@@ -888,7 +918,22 @@ TEST_F(HttpStreamFactoryJobControllerTest, OnStreamFailedForBothJobs) {
EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
}
-TEST_F(HttpStreamFactoryJobControllerTest, AltJobFailsAfterMainJobSucceeds) {
+// This test verifies that the alternative service is not marked broken if both
+// jobs fail, and the alternative job is not retried on the alternate network.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ OnStreamFailedForBothJobsWithoutQuicRetry) {
+ TestOnStreamFailedForBothJobs(false);
+}
+
+// This test verifies that the alternative service is not marked broken if both
+// jobs fail, and the alternative job is retried on the alternate network.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetwork) {
+ TestOnStreamFailedForBothJobs(true);
+}
+
+void HttpStreamFactoryJobControllerTest::TestAltJobFailsAfterMainJobSucceeded(
+ bool alt_job_retried_on_non_default_network) {
quic_data_ = std::make_unique<MockQuicData>();
quic_data_->AddRead(ASYNC, ERR_FAILED);
crypto_client_stream_factory_.set_handshake_mode(
@@ -914,6 +959,12 @@ TEST_F(HttpStreamFactoryJobControllerTest, AltJobFailsAfterMainJobSucceeds) {
EXPECT_TRUE(job_controller_->main_job());
EXPECT_TRUE(job_controller_->alternative_job());
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+
// 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.
@@ -924,10 +975,30 @@ TEST_F(HttpStreamFactoryJobControllerTest, AltJobFailsAfterMainJobSucceeds) {
base::RunLoop().RunUntilIdle();
- VerifyBrokenAlternateProtocolMapping(request_info, true);
// Reset the request as it's been successfully served.
request_.reset();
+ VerifyBrokenAlternateProtocolMapping(request_info, true);
EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
+
+ // Verify the brokenness is not cleared when the default network changes.
+ session_->http_server_properties()->OnDefaultNetworkChanged();
+ VerifyBrokenAlternateProtocolMapping(request_info, true);
+}
+
+// This test verifies that the alternatvie service is marked broken when the
+// alternative job fails on default after the main job succeeded. The
+// brokenness should not be cleared when the default network changes.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobFailsOnDefaultNetworkAfterMainJobSucceeded) {
+ TestAltJobFailsAfterMainJobSucceeded(false);
+}
+
+// This test verifies that the alternatvie service is marked broken when the
+// alternative job fails on both networks after the main job succeeded. The
+// brokenness should not be cleared when the default network changes.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobFailsOnBothNetworksAfterMainJobSucceeded) {
+ TestAltJobFailsAfterMainJobSucceeded(true);
}
// Tests that when alt job succeeds, main job is destroyed.
@@ -1111,7 +1182,8 @@ TEST_F(HttpStreamFactoryJobControllerTest,
EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
}
-TEST_F(HttpStreamFactoryJobControllerTest, AltJobSucceedsAfterMainJobFailed) {
+void HttpStreamFactoryJobControllerTest::TestAltJobSucceedsAfterMainJobFailed(
+ bool alt_job_retried_on_non_default_network) {
quic_data_ = std::make_unique<MockQuicData>();
quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
// Use cold start and complete alt job manually.
@@ -1142,6 +1214,11 @@ TEST_F(HttpStreamFactoryJobControllerTest, AltJobSucceedsAfterMainJobFailed) {
EXPECT_TRUE(job_controller_->alternative_job());
base::RunLoop().RunUntilIdle();
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
// Make |alternative_job| succeed.
auto http_stream = std::make_unique<HttpBasicStream>(
@@ -1158,7 +1235,244 @@ TEST_F(HttpStreamFactoryJobControllerTest, AltJobSucceedsAfterMainJobFailed) {
EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
}
-TEST_F(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobFailed) {
+// This test verifies that the alternative service is not mark broken if the
+// alternative job succeeds on the default network after the main job failed.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobSucceedsOnDefaultNetworkAfterMainJobFailed) {
+ TestAltJobSucceedsAfterMainJobFailed(false);
+}
+
+// This test verifies that the alternative service is not mark broken if the
+// alternative job succeeds on the alternate network after the main job failed.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobSucceedsOnAlternateNetwrokAfterMainJobFailed) {
+ TestAltJobSucceedsAfterMainJobFailed(true);
+}
+
+void HttpStreamFactoryJobControllerTest::
+ TestAltJobSucceedsAfterMainJobSucceeded(
+ bool alt_job_retried_on_non_default_network) {
+ quic_data_ = std::make_unique<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_ = std::make_unique<SequencedSocketData>();
+ tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ SSLSocketDataProvider ssl_data(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
+
+ 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);
+
+ // |main_job| fails but should not report status to Request.
+ EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(0);
+
+ request_ =
+ job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
+ HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+
+ // Run the message loop to make |main_job| succeed and status will be
+ // reported to Request.
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _));
+ base::RunLoop().RunUntilIdle();
+ VerifyBrokenAlternateProtocolMapping(request_info, false);
+
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+
+ // Make |alternative_job| succeed.
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+
+ HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
+ job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
+
+ request_.reset();
+ // If alt job was retried on the alternate network, the alternative service
+ // should be marked broken until the default network changes.
+ VerifyBrokenAlternateProtocolMapping(request_info,
+ alt_job_retried_on_non_default_network);
+ EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
+ if (alt_job_retried_on_non_default_network) {
+ // Verify the brokenness is cleared when the default network changes.
+ session_->http_server_properties()->OnDefaultNetworkChanged();
+ VerifyBrokenAlternateProtocolMapping(request_info, false);
+ }
+}
+
+// This test verifies that the alternative service is not marked broken if the
+// alternative job succeeds on the default network after the main job succeeded.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobSucceedsOnDefaultNetworkAfterMainJobSucceeded) {
+ TestAltJobSucceedsAfterMainJobSucceeded(false);
+}
+
+// This test verifies that the alternative service is marked broken until the
+// default network changes if the alternative job succeeds on the non-default
+// network, which failed on the default network previously, after the main job
+// succeeded. The brokenness should be cleared when the default network
+// changes.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ AltJobSucceedsOnAlternateNetworkAfterMainJobSucceeded) {
+ TestAltJobSucceedsAfterMainJobSucceeded(true);
+}
+
+void HttpStreamFactoryJobControllerTest::
+ TestMainJobSucceedsAfterAltJobSucceeded(
+ bool alt_job_retried_on_non_default_network) {
+ quic_data_ = std::make_unique<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_ = std::make_unique<SequencedSocketData>();
+ tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ SSLSocketDataProvider ssl_data(ASYNC, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
+
+ 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);
+
+ request_ =
+ job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
+ HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+ // Make |alternative_job| succeed.
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream.get()));
+
+ HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
+ job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
+
+ // Run message loop to make the main job succeed.
+ base::RunLoop().RunUntilIdle();
+ // If alt job was retried on the alternate network, the alternative service
+ // should be marked broken until the default network changes.
+ VerifyBrokenAlternateProtocolMapping(request_info,
+ alt_job_retried_on_non_default_network);
+ request_.reset();
+ EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
+ if (alt_job_retried_on_non_default_network) {
+ // Verify the brokenness is cleared when the default network changes.
+ session_->http_server_properties()->OnDefaultNetworkChanged();
+ VerifyBrokenAlternateProtocolMapping(request_info, false);
+ }
+}
+
+// This test verifies that the alternative service is not marked broken if the
+// main job succeeds after the alternative job succeeded on the default network.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobSucceedsAfterAltJobSucceededOnDefaultNetwork) {
+ TestMainJobSucceedsAfterAltJobSucceeded(false);
+}
+
+// This test verifies that the alternative service is marked broken until the
+// default network changes if the main job succeeds after the alternative job
+// succeeded on the non-default network, i.e., failed on the default network
+// previously. The brokenness should be cleared when the default network
+// changes.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobSucceedsAfterAltJobSucceededOnAlternateNetwork) {
+ TestAltJobSucceedsAfterMainJobSucceeded(true);
+}
+
+void HttpStreamFactoryJobControllerTest::TestMainJobFailsAfterAltJobSucceeded(
+ bool alt_job_retried_on_non_default_network) {
+ quic_data_ = std::make_unique<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_ = std::make_unique<SequencedSocketData>();
+ tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
+
+ 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);
+
+ request_ =
+ job_controller_->Start(&request_delegate_, nullptr, net_log_.bound(),
+ HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
+ EXPECT_TRUE(job_controller_->main_job());
+ EXPECT_TRUE(job_controller_->alternative_job());
+
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+ // Make |alternative_job| succeed.
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream.get()));
+
+ HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
+ job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
+
+ // Run message loop to make the main job fail.
+ base::RunLoop().RunUntilIdle();
+ VerifyBrokenAlternateProtocolMapping(request_info, false);
+ request_.reset();
+ EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
+}
+
+// This test verifies that the alternative service is not marked broken if the
+// main job fails after the alternative job succeeded on the default network.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobFailsAfterAltJobSucceededOnDefaultNetwork) {
+ TestMainJobFailsAfterAltJobSucceeded(false);
+}
+
+// This test verifies that the alternative service is not marked broken if the
+// main job fails after the alternative job succeeded on the non-default
+// network, i.e., failed on the default network previously.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobFailsAfterAltJobSucceededOnAlternateNetwork) {
+ TestMainJobFailsAfterAltJobSucceeded(true);
+}
+
+void HttpStreamFactoryJobControllerTest::TestMainJobSucceedsAfterAltJobFailed(
+ bool alt_job_retried_on_non_default_network) {
quic_data_ = std::make_unique<MockQuicData>();
quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
@@ -1189,14 +1503,38 @@ TEST_F(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobFailed) {
// |main_job| succeeds and should report status to Request.
EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _));
+ if (alt_job_retried_on_non_default_network) {
+ // Set the alt job as if it failed on the default network and is retired on
+ // the alternate network.
+ JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
+ }
+
base::RunLoop().RunUntilIdle();
+ request_.reset();
// 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(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
+ // Verify the brokenness is not cleared when the default network changes.
+ session_->http_server_properties()->OnDefaultNetworkChanged();
+ VerifyBrokenAlternateProtocolMapping(request_info, true);
+}
+
+// This test verifies that the alternative service will be marked broken when
+// the alternative job fails on the default network and main job succeeds later.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobSucceedsAfterAltJobFailedOnDefaultNetwork) {
+ TestMainJobSucceedsAfterAltJobFailed(false);
+}
+
+// This test verifies that the alternative service will be marked broken when
+// the alternative job fails on both default and alternate networks and main job
+// succeeds later.
+TEST_F(HttpStreamFactoryJobControllerTest,
+ MainJobSucceedsAfterAltJobFailedOnBothNetworks) {
+ TestMainJobSucceedsAfterAltJobFailed(true);
}
// Verifies that if the alternative job fails due to a connection change event,
@@ -1232,12 +1570,12 @@ TEST_F(HttpStreamFactoryJobControllerTest,
// |main_job| succeeds and should report status to Request.
EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _));
base::RunLoop().RunUntilIdle();
+ request_.reset();
// 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(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
}