Index: net/quic/quic_stream_factory_test.cc |
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc |
index fdc023b28ac5d8420c165d16d3cc5baf0530cb7b..39618db9118845c16f32f970111e1baaca994f36 100644 |
--- a/net/quic/quic_stream_factory_test.cc |
+++ b/net/quic/quic_stream_factory_test.cc |
@@ -135,6 +135,21 @@ class QuicStreamFactoryPeer { |
factory->disable_disk_cache_ = disable_disk_cache; |
} |
+ static void SetMaxNumberOfLossyConnections( |
+ QuicStreamFactory* factory, |
+ int max_number_of_lossy_connections) { |
+ factory->max_number_of_lossy_connections_ = max_number_of_lossy_connections; |
+ } |
+ |
+ static int GetNumberOfLossyConnections(QuicStreamFactory* factory, |
+ uint16 port) { |
+ return factory->number_of_lossy_connections_[port]; |
+ } |
+ |
+ static bool IsQuicDisabled(QuicStreamFactory* factory, uint16 port) { |
+ return factory->IsQuicDisabled(port); |
+ } |
+ |
static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory, |
const QuicServerId& server_id) { |
return (factory->active_jobs_[server_id]).size(); |
@@ -206,6 +221,8 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> { |
/*enable_connection_racing=*/false, |
/*enable_non_blocking_io=*/true, |
/*disable_disk_cache=*/false, |
+ /*max_number_of_lossy_connections=*/0, |
+ /*packet_loss_threshold=*/1.0f, |
/*receive_buffer_size=*/0, |
QuicTagVector()), |
host_port_pair_(kDefaultServerHostName, kDefaultServerPort), |
@@ -1681,5 +1698,140 @@ TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) { |
EXPECT_TRUE(socket_data.at_write_eof()); |
} |
+TEST_P(QuicStreamFactoryTest, BadPacketLoss) { |
+ factory_.set_quic_server_info_factory(&quic_server_info_factory_); |
+ QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get()); |
+ QuicStreamFactoryPeer::SetDisableDiskCache(&factory_, true); |
+ QuicStreamFactoryPeer::SetMaxNumberOfLossyConnections(&factory_, 2); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port())); |
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections( |
+ &factory_, host_port_pair_.port())); |
+ |
+ MockRead reads[] = { |
+ MockRead(ASYNC, OK, 0) // EOF |
+ }; |
+ DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0); |
+ socket_factory_.AddSocketDataProvider(&socket_data); |
+ socket_data.StopAfter(1); |
+ |
+ DeterministicSocketData socket_data2(reads, arraysize(reads), nullptr, 0); |
+ socket_factory_.AddSocketDataProvider(&socket_data2); |
+ socket_data2.StopAfter(1); |
+ |
+ DeterministicSocketData socket_data3(reads, arraysize(reads), nullptr, 0); |
+ socket_factory_.AddSocketDataProvider(&socket_data3); |
+ socket_data3.StopAfter(1); |
+ |
+ HostPortPair server2("mail.example.org", kDefaultServerPort); |
+ HostPortPair server3("docs.example.org", 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", ""); |
+ |
+ QuicStreamRequest request(&factory_); |
+ EXPECT_EQ(OK, request.Request(host_port_pair_, is_https_, privacy_mode_, |
+ "GET", net_log_, callback_.callback())); |
+ |
+ QuicClientSession* session = QuicStreamFactoryPeer::GetActiveSession( |
+ &factory_, host_port_pair_, is_https_); |
+ |
+ 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(QuicStreamFactoryPeer::HasActiveSession( |
+ &factory_, host_port_pair_, is_https_)); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port())); |
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections( |
+ &factory_, host_port_pair_.port())); |
+ |
+ // Set packet_loss_rate to a higher value than packet_loss_threshold only once |
+ // and that should close the session, but shouldn't disable QUIC. |
+ EXPECT_TRUE( |
+ factory_.OnHandshakeConfirmed(session, /*packet_loss_rate=*/1.0f)); |
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections( |
+ &factory_, host_port_pair_.port())); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::IsQuicDisabled(&factory_, host_port_pair_.port())); |
+ EXPECT_FALSE(QuicStreamFactoryPeer::HasActiveSession( |
+ &factory_, host_port_pair_, is_https_)); |
+ EXPECT_EQ(nullptr, CreateIfSessionExists(host_port_pair_, net_log_).get()); |
+ |
+ // Test N-in-a-row high packet loss connections. |
+ |
+ DVLOG(1) << "Create 2nd session and test packet loss"; |
+ |
+ TestCompletionCallback callback2; |
+ QuicStreamRequest request2(&factory_); |
+ EXPECT_EQ(OK, request2.Request(server2, is_https_, privacy_mode_, "GET", |
+ net_log_, callback2.callback())); |
+ QuicClientSession* session2 = |
+ QuicStreamFactoryPeer::GetActiveSession(&factory_, server2, is_https_); |
+ |
+ // 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_, server2.port())); |
+ EXPECT_FALSE( |
+ factory_.OnHandshakeConfirmed(session2, /*packet_loss_rate=*/0.9f)); |
+ EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections( |
+ &factory_, server2.port())); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server2.port())); |
+ |
+ // Set packet_loss_rate to a higher value than packet_loss_threshold only once |
+ // and that should close the session, but shouldn't disable QUIC. |
+ EXPECT_TRUE( |
+ factory_.OnHandshakeConfirmed(session2, /*packet_loss_rate=*/1.0f)); |
+ EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections( |
+ &factory_, server2.port())); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server2.port())); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::HasActiveSession(&factory_, server2, is_https_)); |
+ EXPECT_EQ(nullptr, CreateIfSessionExists(server2, net_log_).get()); |
+ |
+ DVLOG(1) << "Create 3rd session which also has packet loss"; |
+ |
+ TestCompletionCallback callback3; |
+ QuicStreamRequest request3(&factory_); |
+ EXPECT_EQ(OK, request3.Request(server3, is_https_, privacy_mode_, "GET", |
+ net_log_, callback3.callback())); |
+ QuicClientSession* session3 = |
+ QuicStreamFactoryPeer::GetActiveSession(&factory_, server3, is_https_); |
+ |
+ // 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_, server3.port())); |
+ EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(&factory_, server3.port())); |
+ EXPECT_FALSE( |
+ QuicStreamFactoryPeer::HasActiveSession(&factory_, server3, is_https_)); |
+ EXPECT_EQ(nullptr, CreateIfSessionExists(server3, net_log_).get()); |
+ |
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); |
+ EXPECT_TRUE(stream.get()); |
+ scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); |
+ EXPECT_TRUE(stream2.get()); |
+ scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream(); |
+ EXPECT_TRUE(stream3.get()); |
+ EXPECT_TRUE(socket_data.at_read_eof()); |
+ EXPECT_TRUE(socket_data.at_write_eof()); |
+ EXPECT_TRUE(socket_data2.at_read_eof()); |
+ EXPECT_TRUE(socket_data2.at_write_eof()); |
+ EXPECT_TRUE(socket_data3.at_read_eof()); |
+ EXPECT_TRUE(socket_data3.at_write_eof()); |
+} |
+ |
} // namespace test |
} // namespace net |