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 2ce6ef4dcb014c7c3f70f6fabfb5ef305b5ea97d..390508436a288f54bc79828f56c595f34a3b9d4f 100644 |
--- a/net/quic/quic_stream_factory_test.cc |
+++ b/net/quic/quic_stream_factory_test.cc |
@@ -34,6 +34,7 @@ |
#include "testing/gtest/include/gtest/gtest.h" |
using base::StringPiece; |
+using std::ostream; |
using std::string; |
using std::vector; |
@@ -43,6 +44,34 @@ namespace test { |
namespace { |
const char kDefaultServerHostName[] = "www.google.com"; |
const int kDefaultServerPort = 443; |
+ |
+// Run all tests with all the combinations of versions and |
+// enable_connection_racing. |
+struct TestParams { |
+ TestParams(const QuicVersion version, bool enable_connection_racing) |
+ : version(version), enable_connection_racing(enable_connection_racing) {} |
+ |
+ friend ostream& operator<<(ostream& os, const TestParams& p) { |
+ os << "{ version: " << QuicVersionToString(p.version); |
+ os << " enable_connection_racing: " << p.enable_connection_racing << " }"; |
+ return os; |
+ } |
+ |
+ QuicVersion version; |
+ bool enable_connection_racing; |
+}; |
+ |
+// Constructs various test permutations. |
+vector<TestParams> GetTestParams() { |
+ vector<TestParams> params; |
+ QuicVersionVector all_supported_versions = QuicSupportedVersions(); |
+ for (const QuicVersion version : all_supported_versions) { |
+ params.push_back(TestParams(version, false)); |
+ params.push_back(TestParams(version, true)); |
+ } |
+ return params; |
+} |
+ |
} // namespace anonymous |
class QuicStreamFactoryPeer { |
@@ -100,6 +129,16 @@ class QuicStreamFactoryPeer { |
size_t load_server_info_timeout) { |
factory->load_server_info_timeout_ms_ = load_server_info_timeout; |
} |
+ |
+ static void SetEnableConnectionRacing(QuicStreamFactory* factory, |
+ bool enable_connection_racing) { |
+ factory->enable_connection_racing_ = enable_connection_racing; |
+ } |
+ |
+ static size_t GetNumberOfActiveJobs(QuicStreamFactory* factory, |
+ const QuicServerId& server_id) { |
+ return (factory->active_jobs_[server_id]).size(); |
+ } |
}; |
class MockQuicServerInfo : public QuicServerInfo { |
@@ -114,6 +153,8 @@ class MockQuicServerInfo : public QuicServerInfo { |
return ERR_IO_PENDING; |
} |
+ void ResetWaitForDataReadyCallback() override {} |
+ |
void CancelWaitForDataReadyCallback() override {} |
bool IsDataReady() override { return false; } |
@@ -135,14 +176,13 @@ class MockQuicServerInfoFactory : public QuicServerInfoFactory { |
} |
}; |
- |
-class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { |
+class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> { |
protected: |
QuicStreamFactoryTest() |
: random_generator_(0), |
clock_(new MockClock()), |
runner_(new TestTaskRunner(clock_)), |
- maker_(GetParam(), 0, clock_), |
+ maker_(GetParam().version, 0, clock_), |
cert_verifier_(CertVerifier::CreateDefault()), |
channel_id_service_( |
new ChannelIDService(new DefaultChannelIDStore(nullptr), |
@@ -158,19 +198,22 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { |
clock_, |
kDefaultMaxPacketSize, |
std::string(), |
- SupportedVersions(GetParam()), |
+ SupportedVersions(GetParam().version), |
/*enable_port_selection=*/true, |
/*always_require_handshake_confirmation=*/false, |
/*disable_connection_pooling=*/false, |
/*load_server_info_timeout=*/0u, |
/*load_server_info_timeout_srtt_multiplier=*/0.0f, |
/*enable_truncated_connection_ids=*/true, |
+ /*enable_connection_racing=*/false, |
QuicTagVector()), |
host_port_pair_(kDefaultServerHostName, kDefaultServerPort), |
is_https_(false), |
privacy_mode_(PRIVACY_MODE_DISABLED) { |
factory_.set_require_confirmation(false); |
clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); |
+ QuicStreamFactoryPeer::SetEnableConnectionRacing( |
+ &factory_, GetParam().enable_connection_racing); |
} |
scoped_ptr<QuicHttpStream> CreateIfSessionExists( |
@@ -244,7 +287,7 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { |
QuicStreamId stream_id = kClientDataStreamId1; |
return maker_.MakeRstPacket( |
1, true, stream_id, |
- AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam())); |
+ AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam().version)); |
} |
MockQuicServerInfoFactory quic_server_info_factory_; |
@@ -266,8 +309,9 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { |
TestCompletionCallback callback_; |
}; |
-INSTANTIATE_TEST_CASE_P(Version, QuicStreamFactoryTest, |
- ::testing::ValuesIn(QuicSupportedVersions())); |
+INSTANTIATE_TEST_CASE_P(Version, |
+ QuicStreamFactoryTest, |
+ ::testing::ValuesIn(GetTestParams())); |
TEST_P(QuicStreamFactoryTest, CreateIfSessionExists) { |
EXPECT_EQ(nullptr, CreateIfSessionExists(host_port_pair_, net_log_).get()); |
@@ -1562,6 +1606,10 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) { |
} |
TEST_P(QuicStreamFactoryTest, CancelWaitForDataReady) { |
+ // Don't race quic connections when testing cancel reading of server config |
+ // from disk cache. |
+ if (GetParam().enable_connection_racing) |
+ return; |
factory_.set_quic_server_info_factory(&quic_server_info_factory_); |
QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get()); |
const size_t kLoadServerInfoTimeoutMs = 50; |
@@ -1604,5 +1652,52 @@ TEST_P(QuicStreamFactoryTest, CancelWaitForDataReady) { |
EXPECT_TRUE(socket_data.at_write_eof()); |
} |
+TEST_P(QuicStreamFactoryTest, RacingConnections) { |
+ if (!GetParam().enable_connection_racing) |
+ return; |
+ factory_.set_quic_server_info_factory(&quic_server_info_factory_); |
+ QuicStreamFactoryPeer::SetTaskRunner(&factory_, runner_.get()); |
+ const size_t kLoadServerInfoTimeoutMs = 50; |
+ QuicStreamFactoryPeer::SetLoadServerInfoTimeout(&factory_, |
+ kLoadServerInfoTimeoutMs); |
+ |
+ MockRead reads[] = { |
+ MockRead(ASYNC, OK, 0) // EOF |
+ }; |
+ DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0); |
+ socket_factory_.AddSocketDataProvider(&socket_data); |
+ socket_data.StopAfter(1); |
+ |
+ MockRead reads2[] = { |
+ MockRead(ASYNC, 0, 0) // EOF |
+ }; |
+ DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0); |
+ socket_factory_.AddSocketDataProvider(&socket_data2); |
+ socket_data2.StopAfter(1); |
+ |
+ 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", ""); |
+ |
+ QuicStreamRequest request(&factory_); |
+ QuicServerId server_id(host_port_pair_, is_https_, privacy_mode_); |
+ EXPECT_EQ(ERR_IO_PENDING, |
+ request.Request(host_port_pair_, is_https_, privacy_mode_, "GET", |
+ net_log_, callback_.callback())); |
+ EXPECT_EQ(2u, |
+ QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id)); |
+ |
+ runner_->RunNextTask(); |
+ |
+ scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); |
+ EXPECT_TRUE(stream.get()); |
+ EXPECT_TRUE(socket_data.at_read_eof()); |
+ EXPECT_TRUE(socket_data.at_write_eof()); |
+ EXPECT_EQ(0u, |
+ QuicStreamFactoryPeer::GetNumberOfActiveJobs(&factory_, server_id)); |
+} |
+ |
} // namespace test |
} // namespace net |