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) { |