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

Unified Diff: net/quic/chromium/quic_stream_factory_test.cc

Issue 2320313003: Revert of Remove obsolete QUIC disabling code. (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « net/quic/chromium/quic_stream_factory.cc ('k') | net/quic/test_tools/quic_stream_factory_peer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/chromium/quic_stream_factory_test.cc
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc
index 89487b0f6a22c593aca71a82c7460985c2f7a6a0..2ca8dbe9f779857174a7f32dec655cf4b8cc3dba 100644
--- a/net/quic/chromium/quic_stream_factory_test.cc
+++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -90,6 +90,8 @@
const char kDefaultServerHostName[] = "www.example.org";
const char kServer2HostName[] = "mail.example.org";
+const char kServer3HostName[] = "docs.example.org";
+const char kServer4HostName[] = "images.example.org";
const char kDifferentHostname[] = "different.example.com";
const int kDefaultServerPort = 443;
const char kDefaultUrl[] = "https://www.example.org/";
@@ -247,6 +249,11 @@
enable_non_blocking_io_(true),
disable_disk_cache_(false),
prefer_aes_(false),
+ max_number_of_lossy_connections_(0),
+ packet_loss_threshold_(1.0f),
+ max_disabled_reasons_(3),
+ threshold_timeouts_with_open_streams_(2),
+ threshold_public_resets_post_handshake_(2),
receive_buffer_size_(0),
delay_tcp_race_(true),
close_sessions_on_ip_change_(false),
@@ -283,8 +290,10 @@
enable_port_selection_, always_require_handshake_confirmation_,
disable_connection_pooling_, load_server_info_timeout_srtt_multiplier_,
enable_connection_racing_, enable_non_blocking_io_, disable_disk_cache_,
- prefer_aes_, receive_buffer_size_, delay_tcp_race_,
- /*max_server_configs_stored_in_properties*/ 0,
+ prefer_aes_, max_number_of_lossy_connections_, packet_loss_threshold_,
+ max_disabled_reasons_, threshold_timeouts_with_open_streams_,
+ threshold_public_resets_post_handshake_, receive_buffer_size_,
+ delay_tcp_race_, /*max_server_configs_stored_in_properties*/ 0,
close_sessions_on_ip_change_,
disable_quic_on_timeout_with_open_streams_,
idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_,
@@ -536,6 +545,11 @@
bool enable_non_blocking_io_;
bool disable_disk_cache_;
bool prefer_aes_;
+ int max_number_of_lossy_connections_;
+ double packet_loss_threshold_;
+ int max_disabled_reasons_;
+ int threshold_timeouts_with_open_streams_;
+ int threshold_public_resets_post_handshake_;
int receive_buffer_size_;
bool delay_tcp_race_;
bool close_sessions_on_ip_change_;
@@ -3186,16 +3200,182 @@
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
}
-TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
- reduced_ping_timeout_seconds_ = 10;
- disable_disk_cache_ = true;
- Initialize();
- ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+TEST_P(QuicStreamFactoryTest, BadPacketLoss) {
+ disable_disk_cache_ = false;
+ max_number_of_lossy_connections_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
- EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data3;
+ socket_data3.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data4;
+ socket_data4.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::ZERO_RTT);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+
+ DVLOG(1) << "Create 1st session and test packet loss";
+
+ // Set packet_loss_rate to a lower value than packet_loss_threshold.
+ EXPECT_FALSE(
+ factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/0.9f));
+ EXPECT_TRUE(session->connection()->connected());
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ // Set packet_loss_rate to a higher value than packet_loss_threshold only once
+ // and that shouldn't close the session and it shouldn't disable QUIC.
+ EXPECT_FALSE(
+ factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/1.0f));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+ EXPECT_TRUE(session->connection()->connected());
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+
+ // Test N-in-a-row high packet loss connections.
+
+ DVLOG(1) << "Create 2nd session and test packet loss";
+
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ // If there is no packet loss during handshake confirmation, number of lossy
+ // connections for the port should be 0.
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), server2.port()));
+ EXPECT_FALSE(
+ factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/0.9f));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), server2.port()));
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
+
+ // Set packet_loss_rate to a higher value than packet_loss_threshold only once
+ // and that shouldn't close the session and it shouldn't disable QUIC.
+ EXPECT_FALSE(
+ factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/1.0f));
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), server2.port()));
+ EXPECT_TRUE(session2->connection()->connected());
+ EXPECT_FALSE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
+ EXPECT_TRUE(HasActiveSession(server2));
+
+ DVLOG(1) << "Create 3rd session which also has packet loss";
+
+ TestCompletionCallback callback3;
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
+ /*cert_verify_flags=*/0, url3_, "GET",
+ net_log_, callback3.callback()));
+ QuicChromiumClientSession* session3 = GetActiveSession(server3);
+
+ DVLOG(1) << "Create 4th session with packet loss and test IsQuicDisabled()";
+ TestCompletionCallback callback4;
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
+ /*cert_verify_flags=*/0, url4_, "GET",
+ net_log_, callback4.callback()));
+ QuicChromiumClientSession* session4 = GetActiveSession(server4);
+
+ // Set packet_loss_rate to higher value than packet_loss_threshold 2nd time in
+ // a row and that should close the session and disable QUIC.
+ EXPECT_TRUE(
+ factory_->OnHandshakeConfirmed(session3, /*packet_loss_rate=*/1.0f));
+ EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), server3.port()));
+ EXPECT_FALSE(session3->connection()->connected());
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server3.port()));
+ EXPECT_FALSE(HasActiveSession(server3));
+
+ // Set packet_loss_rate to higher value than packet_loss_threshold 3rd time in
+ // a row and IsQuicDisabled() should close the session.
+ EXPECT_TRUE(
+ factory_->OnHandshakeConfirmed(session4, /*packet_loss_rate=*/1.0f));
+ EXPECT_EQ(3, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), server4.port()));
+ EXPECT_FALSE(session4->connection()->connected());
+ EXPECT_TRUE(
+ QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server4.port()));
+ EXPECT_FALSE(HasActiveSession(server4));
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_TRUE(stream.get());
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_TRUE(stream2.get());
+ std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
+ EXPECT_TRUE(stream3.get());
+ std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
+ EXPECT_TRUE(stream4.get());
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data3.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data4.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
+ disable_disk_cache_ = false;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
MockQuicData socket_data;
socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
@@ -3214,18 +3394,96 @@
"192.168.0.1", "");
host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
- // Quic should use default PING timeout when no previous connection times out
- // with open stream.
- EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
- QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
QuicStreamRequest request(factory_.get());
EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
/*cert_verify_flags=*/0, url_, "GET", net_log_,
callback_.callback()));
QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
- EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
- session->connection()->ping_timeout());
+
+ DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
+ session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ // Test two-in-a-row public reset post handshakes..
+ DVLOG(1) << "Create 2nd session and trigger public reset post handshake";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ session2->connection()->CloseConnection(
+ QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(
+ QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_FALSE(stream.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_FALSE(stream2.get()); // Session is already closed.
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
+ disable_disk_cache_ = true;
+ threshold_timeouts_with_open_streams_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
EXPECT_TRUE(stream.get());
@@ -3242,7 +3500,115 @@
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ // Test two-in-a-row timeouts with open streams.
+ DVLOG(1) << "Create 2nd session and timeout with open stream";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_TRUE(stream2.get());
+ EXPECT_EQ(OK, stream2->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ session2->connection()->CloseConnection(
+ QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(
+ 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
+
+ // Verify that QUIC is un-disabled after a TCP job fails.
+ factory_->OnTcpJobCompleted(/*succeeded=*/false);
+ EXPECT_EQ(
+ 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
+ reduced_ping_timeout_seconds_ = 10;
+ disable_disk_cache_ = true;
+ threshold_timeouts_with_open_streams_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+
+ // Quic should use default PING timeout when no previous connection times out
+ // with open stream.
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
+ session->connection()->ping_timeout());
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_TRUE(stream.get());
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ DVLOG(1)
+ << "Created 1st session and initialized a stream. Now trigger timeout";
+ session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
// The first connection times out with open stream, QUIC should reduce initial
// PING time for subsequent connections.
@@ -3270,12 +3636,270 @@
// QuicStreamFactory::OnSessionClosed() runs.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
- EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+ EXPECT_EQ(
+ 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
+
+ // Verify that QUIC is un-disabled after a TCP job fails.
+ factory_->OnTcpJobCompleted(/*succeeded=*/false);
+ EXPECT_EQ(
+ 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
EXPECT_TRUE(socket_data.AllReadDataConsumed());
EXPECT_TRUE(socket_data.AllWriteDataConsumed());
EXPECT_TRUE(socket_data2.AllReadDataConsumed());
EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data3;
+ socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data3.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
+
+ // Test first and third out of three public reset post handshakes.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+
+ DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
+ session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 2nd session without disable trigger";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ session2->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 3rd session with public reset post handshake,"
+ << " will disable QUIC";
+ TestCompletionCallback callback3;
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
+ /*cert_verify_flags=*/0, url3_, "GET",
+ net_log_, callback3.callback()));
+ QuicChromiumClientSession* session3 = GetActiveSession(server3);
+
+ session3->connection()->CloseConnection(
+ QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+ EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(
+ QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_FALSE(stream.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_FALSE(stream2.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
+ EXPECT_FALSE(stream3.get()); // Session is already closed.
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data3.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data3;
+ socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data3.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
+
+ // Test first and third out of three timeouts with open streams.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_TRUE(stream.get());
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ DVLOG(1)
+ << "Created 1st session and initialized a stream. Now trigger timeout";
+ session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ // Test two-in-a-row timeouts with open streams.
+ DVLOG(1) << "Create 2nd session without timeout";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ session2->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 3rd session with timeout with open streams,"
+ << " will disable QUIC";
+
+ TestCompletionCallback callback3;
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
+ /*cert_verify_flags=*/0, url3_, "GET",
+ net_log_, callback3.callback()));
+ QuicChromiumClientSession* session3 = GetActiveSession(server3);
+
+ std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
+ EXPECT_TRUE(stream3.get());
+ EXPECT_EQ(OK, stream3->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+ session3->connection()->CloseConnection(
+ QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+ EXPECT_EQ(
+ 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
+
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_FALSE(stream2.get()); // Session is already closed.
+
+ // Verify that QUIC is un-disabled after a network change.
+ factory_->OnIPAddressChanged();
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(
+ 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data3.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, DisableQuicWhenTimeoutsWithOpenStreams) {
@@ -3286,7 +3910,10 @@
crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
- EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
MockQuicData socket_data;
socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
@@ -3322,18 +3949,318 @@
base::RunLoop run_loop;
run_loop.RunUntilIdle();
- EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
+ factory_->QuicDisabledReason(host_port_pair_.port()));
// Verify that QUIC is fully disabled after a TCP job succeeds.
factory_->OnTcpJobCompleted(/*succeeded=*/true);
- EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
// Verify that QUIC stays disabled after a TCP job succeeds.
factory_->OnTcpJobCompleted(/*succeeded=*/false);
- EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
-
- EXPECT_TRUE(socket_data.AllReadDataConsumed());
- EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data3;
+ socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data3.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data4;
+ socket_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data4.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
+
+ // Test first and fourth out of four public reset post handshakes.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+
+ DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
+ session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 2nd and 3rd sessions without disable trigger";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ session2->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ TestCompletionCallback callback3;
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
+ /*cert_verify_flags=*/0, url3_, "GET",
+ net_log_, callback3.callback()));
+ QuicChromiumClientSession* session3 = GetActiveSession(server3);
+
+ session3->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 4rd session with public reset post handshake,"
+ << " will not disable QUIC";
+ TestCompletionCallback callback4;
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
+ /*cert_verify_flags=*/0, url4_, "GET",
+ net_log_, callback4.callback()));
+ QuicChromiumClientSession* session4 = GetActiveSession(server4);
+
+ session4->connection()->CloseConnection(
+ QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop4;
+ run_loop4.RunUntilIdle();
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
+ factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_FALSE(stream.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_FALSE(stream2.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
+ EXPECT_FALSE(stream3.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
+ EXPECT_FALSE(stream4.get()); // Session is already closed.
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data3.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data4.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
+ disable_disk_cache_ = true;
+ threshold_public_resets_post_handshake_ = 2;
+ Initialize();
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
+
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
+ factory_.get(), host_port_pair_.port()));
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data3;
+ socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data3.AddSocketDataToFactory(&socket_factory_);
+
+ MockQuicData socket_data4;
+ socket_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data4.AddSocketDataToFactory(&socket_factory_);
+
+ HostPortPair server2(kServer2HostName, kDefaultServerPort);
+ HostPortPair server3(kServer3HostName, kDefaultServerPort);
+ HostPortPair server4(kServer4HostName, kDefaultServerPort);
+
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
+ host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
+
+ // Test first and fourth out of three timeouts with open streams.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+
+ QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
+
+ std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
+ EXPECT_TRUE(stream.get());
+ HttpRequestInfo request_info;
+ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+
+ DVLOG(1)
+ << "Created 1st session and initialized a stream. Now trigger timeout";
+ session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 2nd and 3rd sessions without timeout";
+ TestCompletionCallback callback2;
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
+ /*cert_verify_flags=*/0, url2_, "GET",
+ net_log_, callback2.callback()));
+ QuicChromiumClientSession* session2 = GetActiveSession(server2);
+
+ session2->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop2;
+ run_loop2.RunUntilIdle();
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ TestCompletionCallback callback3;
+ QuicStreamRequest request3(factory_.get());
+ EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
+ /*cert_verify_flags=*/0, url3_, "GET",
+ net_log_, callback3.callback()));
+ QuicChromiumClientSession* session3 = GetActiveSession(server3);
+
+ session3->connection()->CloseConnection(
+ QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop3;
+ run_loop3.RunUntilIdle();
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ DVLOG(1) << "Create 4th session with timeout with open streams,"
+ << " will not disable QUIC";
+
+ TestCompletionCallback callback4;
+ QuicStreamRequest request4(factory_.get());
+ EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
+ /*cert_verify_flags=*/0, url4_, "GET",
+ net_log_, callback4.callback()));
+ QuicChromiumClientSession* session4 = GetActiveSession(server4);
+
+ std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
+ EXPECT_TRUE(stream4.get());
+ EXPECT_EQ(OK, stream4->InitializeStream(&request_info, DEFAULT_PRIORITY,
+ net_log_, CompletionCallback()));
+ session4->connection()->CloseConnection(
+ QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
+ // Need to spin the loop now to ensure that
+ // QuicStreamFactory::OnSessionClosed() runs.
+ base::RunLoop run_loop4;
+ run_loop4.RunUntilIdle();
+ EXPECT_EQ(
+ 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+ EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+ host_port_pair_.port()));
+
+ std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
+ EXPECT_FALSE(stream2.get()); // Session is already closed.
+ std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
+ EXPECT_FALSE(stream3.get()); // Session is already closed.
+
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data3.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data4.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
}
TEST_P(QuicStreamFactoryTest, EnableDelayTcpRace) {
« no previous file with comments | « net/quic/chromium/quic_stream_factory.cc ('k') | net/quic/test_tools/quic_stream_factory_peer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698