| Index: net/quic/core/quic_server_session_base_test.cc
|
| diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc
|
| index 501e0a9390d28e8a94bc3c2a7fa2c97339745244..371f4aa5ac2e4a291082754f25d042709c43a0e6 100644
|
| --- a/net/quic/core/quic_server_session_base_test.cc
|
| +++ b/net/quic/core/quic_server_session_base_test.cc
|
| @@ -16,8 +16,10 @@
|
| #include "net/quic/core/quic_crypto_server_stream.h"
|
| #include "net/quic/core/quic_utils.h"
|
| #include "net/quic/test_tools/crypto_test_utils.h"
|
| +#include "net/quic/test_tools/fake_proof_source.h"
|
| #include "net/quic/test_tools/quic_config_peer.h"
|
| #include "net/quic/test_tools/quic_connection_peer.h"
|
| +#include "net/quic/test_tools/quic_crypto_server_config_peer.h"
|
| #include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
|
| #include "net/quic/test_tools/quic_session_peer.h"
|
| #include "net/quic/test_tools/quic_spdy_session_peer.h"
|
| @@ -124,9 +126,12 @@ const size_t kMaxStreamsForTest = 10;
|
| class QuicServerSessionBaseTest : public ::testing::TestWithParam<QuicVersion> {
|
| protected:
|
| QuicServerSessionBaseTest()
|
| + : QuicServerSessionBaseTest(CryptoTestUtils::ProofSourceForTesting()) {}
|
| +
|
| + explicit QuicServerSessionBaseTest(std::unique_ptr<ProofSource> proof_source)
|
| : crypto_config_(QuicCryptoServerConfig::TESTING,
|
| QuicRandom::GetInstance(),
|
| - CryptoTestUtils::ProofSourceForTesting()),
|
| + std::move(proof_source)),
|
| compressed_certs_cache_(
|
| QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {
|
| config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
|
| @@ -185,7 +190,6 @@ MATCHER_P(EqualsProto, network_params, "") {
|
| INSTANTIATE_TEST_CASE_P(Tests,
|
| QuicServerSessionBaseTest,
|
| ::testing::ValuesIn(AllSupportedVersions()));
|
| -
|
| TEST_P(QuicServerSessionBaseTest, ServerPushDisabledByDefault) {
|
| FLAGS_quic_enable_server_push_by_default = true;
|
| // Without the client explicitly sending kSPSH, server push will be disabled
|
| @@ -573,6 +577,79 @@ TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
|
| QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
|
| }
|
|
|
| +// Tests which check the lifetime management of data members of
|
| +// QuicCryptoServerStream objects when async GetProof is in use.
|
| +class StreamMemberLifetimeTest : public QuicServerSessionBaseTest {
|
| + public:
|
| + StreamMemberLifetimeTest()
|
| + : QuicServerSessionBaseTest(
|
| + std::unique_ptr<FakeProofSource>(new FakeProofSource())),
|
| + crypto_config_peer_(&crypto_config_) {
|
| + GetFakeProofSource()->Activate();
|
| + }
|
| +
|
| + FakeProofSource* GetFakeProofSource() const {
|
| + return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
|
| + }
|
| +
|
| + private:
|
| + QuicCryptoServerConfigPeer crypto_config_peer_;
|
| +};
|
| +
|
| +INSTANTIATE_TEST_CASE_P(StreamMemberLifetimeTests,
|
| + StreamMemberLifetimeTest,
|
| + ::testing::ValuesIn(AllSupportedVersions()));
|
| +
|
| +// Trigger an operation which causes an async invocation of
|
| +// ProofSource::GetProof. Delay the completion of the operation until after the
|
| +// stream has been destroyed, and verify that there are no memory bugs.
|
| +TEST_P(StreamMemberLifetimeTest, Basic) {
|
| + FLAGS_enable_async_get_proof = true;
|
| + FLAGS_quic_buffer_packet_till_chlo = true;
|
| + FLAGS_enable_quic_stateless_reject_support = true;
|
| + FLAGS_quic_use_cheap_stateless_rejects = true;
|
| + FLAGS_quic_create_session_after_insertion = true;
|
| +
|
| + const QuicClock* clock = helper_.GetClock();
|
| + QuicVersion version = AllSupportedVersions().front();
|
| + CryptoHandshakeMessage chlo = CryptoTestUtils::GenerateDefaultInchoateCHLO(
|
| + clock, version, &crypto_config_);
|
| + chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
|
| + std::vector<QuicVersion> packet_version_list = {version};
|
| + std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
|
| + 1, true, false, false, kDefaultPathId, 1,
|
| + chlo.GetSerialized().AsStringPiece().as_string(),
|
| + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
|
| + &packet_version_list));
|
| +
|
| + EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _))
|
| + .WillOnce(testing::Return(true));
|
| + EXPECT_CALL(stream_helper_, GenerateConnectionIdForReject(_))
|
| + .WillOnce(testing::Return(12345));
|
| +
|
| + // Set the current packet
|
| + QuicConnectionPeer::SetCurrentPacket(session_->connection(),
|
| + packet->AsStringPiece());
|
| +
|
| + // Yes, this is horrible. But it's the easiest way to trigger the behavior we
|
| + // need to exercise.
|
| + QuicCryptoServerStreamBase* crypto_stream =
|
| + const_cast<QuicCryptoServerStreamBase*>(session_->crypto_stream());
|
| +
|
| + // Feed the CHLO into the crypto stream, which will trigger a call to
|
| + // ProofSource::GetProof
|
| + crypto_stream->OnHandshakeMessage(chlo);
|
| + ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
|
| +
|
| + // Destroy the stream
|
| + session_.reset();
|
| +
|
| + // Allow the async ProofSource::GetProof call to complete. Verify (under
|
| + // asan) that this does not result in accesses to any freed memory from the
|
| + // session or its subobjects.
|
| + GetFakeProofSource()->InvokePendingCallback(0);
|
| +}
|
| +
|
| } // namespace
|
| } // namespace test
|
| } // namespace net
|
|
|