// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Common utilities for Quic tests

#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
#define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_

#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/congestion_control/loss_detection_interface.h"
#include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
#include "quiche/quic/core/crypto/transport_parameters.h"
#include "quiche/quic/core/http/http_decoder.h"
#include "quiche/quic/core/http/quic_client_push_promise_index.h"
#include "quiche/quic/core/http/quic_server_session_base.h"
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_connection_id.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_path_validator.h"
#include "quiche/quic/core/quic_sent_packet_manager.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/mock_clock.h"
#include "quiche/quic/test_tools/mock_quic_session_visitor.h"
#include "quiche/quic/test_tools/mock_random.h"
#include "quiche/quic/test_tools/quic_framer_peer.h"
#include "quiche/quic/test_tools/simple_quic_framer.h"
#include "quiche/common/quiche_mem_slice_storage.h"
#include "quiche/common/simple_buffer_allocator.h"
#include "quiche/spdy/core/http2_header_block.h"

namespace quic {

namespace test {

// A generic predictable connection ID suited for testing.
QuicConnectionId TestConnectionId();

// A generic predictable connection ID suited for testing, generated from a
// given number, such as an index.
QuicConnectionId TestConnectionId(uint64_t connection_number);

// A generic predictable connection ID suited for testing, generated from a
// given number, such as an index. Guaranteed to be 9 bytes long.
QuicConnectionId TestConnectionIdNineBytesLong(uint64_t connection_number);

// Extracts the connection number passed to TestConnectionId().
uint64_t TestConnectionIdToUInt64(QuicConnectionId connection_id);

enum : uint16_t { kTestPort = 12345 };
enum : uint32_t {
  kMaxDatagramFrameSizeForTest = 1333,
  kMaxPacketSizeForTest = 9001,
  kInitialStreamFlowControlWindowForTest = 1024 * 1024,   // 1 MB
  kInitialSessionFlowControlWindowForTest = 1536 * 1024,  // 1.5 MB
};

enum : uint64_t {
  kAckDelayExponentForTest = 10,
  kMaxAckDelayForTest = 51,  // ms
  kActiveConnectionIdLimitForTest = 52,
  kMinAckDelayUsForTest = 1000
};

// Create an arbitrary stateless reset token, same across multiple calls.
std::vector<uint8_t> CreateStatelessResetTokenForTest();

// A hostname useful for testing, returns "test.example.org".
std::string TestHostname();

// A server ID useful for testing, returns test.example.org:12345.
QuicServerId TestServerId();

// Returns the test peer IP address.
QuicIpAddress TestPeerIPAddress();

// Upper limit on versions we support.
ParsedQuicVersion QuicVersionMax();

// Lower limit on versions we support.
ParsedQuicVersion QuicVersionMin();

// Disables all flags that enable QUIC versions that use TLS.
// This is only meant as a temporary measure to prevent some broken tests
// from running with TLS.
void DisableQuicVersionsWithTls();

// Create an encrypted packet for testing.
// If versions == nullptr, uses &AllSupportedVersions().
// Note that the packet is encrypted with NullEncrypter, so to decrypt the
// constructed packet, the framer must be set to use NullDecrypter.
QuicEncryptedPacket* ConstructEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data, bool full_padding,
    QuicConnectionIdIncluded destination_connection_id_included,
    QuicConnectionIdIncluded source_connection_id_included,
    QuicPacketNumberLength packet_number_length,
    ParsedQuicVersionVector* versions, Perspective perspective);

QuicEncryptedPacket* ConstructEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data, bool full_padding,
    QuicConnectionIdIncluded destination_connection_id_included,
    QuicConnectionIdIncluded source_connection_id_included,
    QuicPacketNumberLength packet_number_length,
    ParsedQuicVersionVector* versions);

// Create an encrypted packet for testing.
// If versions == nullptr, uses &AllSupportedVersions().
// Note that the packet is encrypted with NullEncrypter, so to decrypt the
// constructed packet, the framer must be set to use NullDecrypter.
QuicEncryptedPacket* ConstructEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data,
    QuicConnectionIdIncluded destination_connection_id_included,
    QuicConnectionIdIncluded source_connection_id_included,
    QuicPacketNumberLength packet_number_length,
    ParsedQuicVersionVector* versions);

// This form assumes |versions| == nullptr.
QuicEncryptedPacket* ConstructEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data,
    QuicConnectionIdIncluded destination_connection_id_included,
    QuicConnectionIdIncluded source_connection_id_included,
    QuicPacketNumberLength packet_number_length);

// This form assumes |connection_id_length| == PACKET_8BYTE_CONNECTION_ID,
// |packet_number_length| == PACKET_4BYTE_PACKET_NUMBER and
// |versions| == nullptr.
QuicEncryptedPacket* ConstructEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data);

// Creates a client-to-server ZERO-RTT packet that will fail to decrypt.
std::unique_ptr<QuicEncryptedPacket> GetUndecryptableEarlyPacket(
    const ParsedQuicVersion& version,
    const QuicConnectionId& server_connection_id);

// Constructs a received packet for testing. The caller must take ownership
// of the returned pointer.
QuicReceivedPacket* ConstructReceivedPacket(
    const QuicEncryptedPacket& encrypted_packet, QuicTime receipt_time);

// Create an encrypted packet for testing whose data portion erroneous.
// The specific way the data portion is erroneous is not specified, but
// it is an error that QuicFramer detects.
// Note that the packet is encrypted with NullEncrypter, so to decrypt the
// constructed packet, the framer must be set to use NullDecrypter.
QuicEncryptedPacket* ConstructMisFramedEncryptedPacket(
    QuicConnectionId destination_connection_id,
    QuicConnectionId source_connection_id, bool version_flag, bool reset_flag,
    uint64_t packet_number, const std::string& data,
    QuicConnectionIdIncluded destination_connection_id_included,
    QuicConnectionIdIncluded source_connection_id_included,
    QuicPacketNumberLength packet_number_length, ParsedQuicVersion version,
    Perspective perspective);

// Returns QuicConfig set to default values.
QuicConfig DefaultQuicConfig();

ParsedQuicVersionVector SupportedVersions(ParsedQuicVersion version);

struct QuicAckBlock {
  QuicPacketNumber start;  // Included
  QuicPacketNumber limit;  // Excluded
};

// Testing convenience method to construct a QuicAckFrame with arbitrary ack
// blocks. Each block is given by a (closed-open) range of packet numbers. e.g.:
// InitAckFrame({{1, 10}})
//   => 1 ack block acking packet numbers 1 to 9.
//
// InitAckFrame({{1, 2}, {3, 4}})
//   => 2 ack blocks acking packet 1 and 3. Packet 2 is missing.
QuicAckFrame InitAckFrame(const std::vector<QuicAckBlock>& ack_blocks);

// Testing convenience method to construct a QuicAckFrame with 1 ack block which
// covers packet number range [1, |largest_acked| + 1).
// Equivalent to InitAckFrame({{1, largest_acked + 1}})
QuicAckFrame InitAckFrame(uint64_t largest_acked);
QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked);

// Testing convenience method to construct a QuicAckFrame with |num_ack_blocks|
// ack blocks of width 1 packet, starting from |least_unacked| + 2.
QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
                                       uint64_t least_unacked);

// Testing convenice method to construct a QuicAckFrame with |largest_acked|,
// ack blocks of width 1 packet and |gap_size|.
QuicAckFrame MakeAckFrameWithGaps(uint64_t gap_size, size_t max_num_gaps,
                                  uint64_t largest_acked);

// Returns the encryption level that corresponds to the header type in
// |header|. If the header is for GOOGLE_QUIC_PACKET instead of an
// IETF-invariants packet, this function returns ENCRYPTION_INITIAL.
EncryptionLevel HeaderToEncryptionLevel(const QuicPacketHeader& header);

// Returns a QuicPacket that is owned by the caller, and
// is populated with the fields in |header| and |frames|, or is nullptr if the
// packet could not be created.
std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
    QuicFramer* framer, const QuicPacketHeader& header,
    const QuicFrames& frames);
// Returns a QuicPacket that is owned by the caller, and of size |packet_size|.
std::unique_ptr<QuicPacket> BuildUnsizedDataPacket(
    QuicFramer* framer, const QuicPacketHeader& header,
    const QuicFrames& frames, size_t packet_size);

// Compute SHA-1 hash of the supplied std::string.
std::string Sha1Hash(absl::string_view data);

// Delete |frame| and return true.
bool ClearControlFrame(const QuicFrame& frame);
bool ClearControlFrameWithTransmissionType(const QuicFrame& frame,
                                           TransmissionType type);

// Simple random number generator used to compute random numbers suitable
// for pseudo-randomly dropping packets in tests.
class SimpleRandom : public QuicRandom {
 public:
  SimpleRandom() { set_seed(0); }
  SimpleRandom(const SimpleRandom&) = delete;
  SimpleRandom& operator=(const SimpleRandom&) = delete;
  ~SimpleRandom() override {}

  // Generates |len| random bytes in the |data| buffer.
  void RandBytes(void* data, size_t len) override;
  // Returns a random number in the range [0, kuint64max].
  uint64_t RandUint64() override;

  // InsecureRandBytes behaves equivalently to RandBytes.
  void InsecureRandBytes(void* data, size_t len) override;
  // InsecureRandUint64 behaves equivalently to RandUint64.
  uint64_t InsecureRandUint64() override;

  void set_seed(uint64_t seed);

 private:
  uint8_t buffer_[4096];
  size_t buffer_offset_ = 0;
  uint8_t key_[32];

  void FillBuffer();
};

class MockFramerVisitor : public QuicFramerVisitorInterface {
 public:
  MockFramerVisitor();
  MockFramerVisitor(const MockFramerVisitor&) = delete;
  MockFramerVisitor& operator=(const MockFramerVisitor&) = delete;
  ~MockFramerVisitor() override;

  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
  // The constructor sets this up to return false by default.
  MOCK_METHOD(bool, OnProtocolVersionMismatch, (ParsedQuicVersion version),
              (override));
  MOCK_METHOD(void, OnPacket, (), (override));
  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket& header),
              (override));
  MOCK_METHOD(void, OnVersionNegotiationPacket,
              (const QuicVersionNegotiationPacket& packet), (override));
  MOCK_METHOD(void, OnRetryPacket,
              (QuicConnectionId original_connection_id,
               QuicConnectionId new_connection_id,
               absl::string_view retry_token,
               absl::string_view retry_integrity_tag,
               absl::string_view retry_without_tag),
              (override));
  // The constructor sets this up to return true by default.
  MOCK_METHOD(bool, OnUnauthenticatedHeader, (const QuicPacketHeader& header),
              (override));
  // The constructor sets this up to return true by default.
  MOCK_METHOD(bool, OnUnauthenticatedPublicHeader,
              (const QuicPacketHeader& header), (override));
  MOCK_METHOD(void, OnDecryptedPacket, (size_t length, EncryptionLevel level),
              (override));
  MOCK_METHOD(bool, OnPacketHeader, (const QuicPacketHeader& header),
              (override));
  MOCK_METHOD(void, OnCoalescedPacket, (const QuicEncryptedPacket& packet),
              (override));
  MOCK_METHOD(void, OnUndecryptablePacket,
              (const QuicEncryptedPacket& packet,
               EncryptionLevel decryption_level, bool has_decryption_key),
              (override));
  MOCK_METHOD(bool, OnStreamFrame, (const QuicStreamFrame& frame), (override));
  MOCK_METHOD(bool, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
  MOCK_METHOD(bool, OnAckFrameStart, (QuicPacketNumber, QuicTime::Delta),
              (override));
  MOCK_METHOD(bool, OnAckRange, (QuicPacketNumber, QuicPacketNumber),
              (override));
  MOCK_METHOD(bool, OnAckTimestamp, (QuicPacketNumber, QuicTime), (override));
  MOCK_METHOD(bool, OnAckFrameEnd, (QuicPacketNumber), (override));
  MOCK_METHOD(bool, OnStopWaitingFrame, (const QuicStopWaitingFrame& frame),
              (override));
  MOCK_METHOD(bool, OnPaddingFrame, (const QuicPaddingFrame& frame),
              (override));
  MOCK_METHOD(bool, OnPingFrame, (const QuicPingFrame& frame), (override));
  MOCK_METHOD(bool, OnRstStreamFrame, (const QuicRstStreamFrame& frame),
              (override));
  MOCK_METHOD(bool, OnConnectionCloseFrame,
              (const QuicConnectionCloseFrame& frame), (override));
  MOCK_METHOD(bool, OnNewConnectionIdFrame,
              (const QuicNewConnectionIdFrame& frame), (override));
  MOCK_METHOD(bool, OnRetireConnectionIdFrame,
              (const QuicRetireConnectionIdFrame& frame), (override));
  MOCK_METHOD(bool, OnNewTokenFrame, (const QuicNewTokenFrame& frame),
              (override));
  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
              (override));
  MOCK_METHOD(bool, OnPathChallengeFrame, (const QuicPathChallengeFrame& frame),
              (override));
  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame& frame),
              (override));
  MOCK_METHOD(bool, OnGoAwayFrame, (const QuicGoAwayFrame& frame), (override));
  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
              (override));
  MOCK_METHOD(bool, OnStreamsBlockedFrame,
              (const QuicStreamsBlockedFrame& frame), (override));
  MOCK_METHOD(bool, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
              (override));
  MOCK_METHOD(bool, OnBlockedFrame, (const QuicBlockedFrame& frame),
              (override));
  MOCK_METHOD(bool, OnMessageFrame, (const QuicMessageFrame& frame),
              (override));
  MOCK_METHOD(bool, OnHandshakeDoneFrame, (const QuicHandshakeDoneFrame& frame),
              (override));
  MOCK_METHOD(bool, OnAckFrequencyFrame, (const QuicAckFrequencyFrame& frame),
              (override));
  MOCK_METHOD(void, OnPacketComplete, (), (override));
  MOCK_METHOD(bool, IsValidStatelessResetToken, (const StatelessResetToken&),
              (const, override));
  MOCK_METHOD(void, OnAuthenticatedIetfStatelessResetPacket,
              (const QuicIetfStatelessResetPacket&), (override));
  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
  MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override));
  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
              (override));
};

class NoOpFramerVisitor : public QuicFramerVisitorInterface {
 public:
  NoOpFramerVisitor() {}
  NoOpFramerVisitor(const NoOpFramerVisitor&) = delete;
  NoOpFramerVisitor& operator=(const NoOpFramerVisitor&) = delete;

  void OnError(QuicFramer* /*framer*/) override {}
  void OnPacket() override {}
  void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
  void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& /*packet*/) override {}
  void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
                     QuicConnectionId /*new_connection_id*/,
                     absl::string_view /*retry_token*/,
                     absl::string_view /*retry_integrity_tag*/,
                     absl::string_view /*retry_without_tag*/) override {}
  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
  void OnDecryptedPacket(size_t /*length*/,
                         EncryptionLevel /*level*/) override {}
  bool OnPacketHeader(const QuicPacketHeader& header) override;
  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override;
  void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
                             EncryptionLevel decryption_level,
                             bool has_decryption_key) override;
  bool OnStreamFrame(const QuicStreamFrame& frame) override;
  bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
  bool OnAckFrameStart(QuicPacketNumber largest_acked,
                       QuicTime::Delta ack_delay_time) override;
  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override;
  bool OnAckTimestamp(QuicPacketNumber packet_number,
                      QuicTime timestamp) override;
  bool OnAckFrameEnd(QuicPacketNumber start) override;
  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
  bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
  bool OnPingFrame(const QuicPingFrame& frame) override;
  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override;
  bool OnRetireConnectionIdFrame(
      const QuicRetireConnectionIdFrame& frame) override;
  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override;
  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override;
  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override;
  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
  bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override;
  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;
  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
  bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
  bool OnMessageFrame(const QuicMessageFrame& frame) override;
  bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override;
  bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override;
  void OnPacketComplete() override {}
  bool IsValidStatelessResetToken(
      const StatelessResetToken& token) const override;
  void OnAuthenticatedIetfStatelessResetPacket(
      const QuicIetfStatelessResetPacket& /*packet*/) override {}
  void OnKeyUpdate(KeyUpdateReason /*reason*/) override {}
  void OnDecryptedFirstPacketInKeyPhase() override {}
  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
      override {
    return nullptr;
  }
  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
    return nullptr;
  }
};

class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
 public:
  MockQuicConnectionVisitor();
  MockQuicConnectionVisitor(const MockQuicConnectionVisitor&) = delete;
  MockQuicConnectionVisitor& operator=(const MockQuicConnectionVisitor&) =
      delete;
  ~MockQuicConnectionVisitor() override;

  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame& frame), (override));
  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame& frame), (override));
  MOCK_METHOD(void, OnWindowUpdateFrame, (const QuicWindowUpdateFrame& frame),
              (override));
  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame& frame),
              (override));
  MOCK_METHOD(void, OnRstStream, (const QuicRstStreamFrame& frame), (override));
  MOCK_METHOD(void, OnGoAway, (const QuicGoAwayFrame& frame), (override));
  MOCK_METHOD(void, OnMessageReceived, (absl::string_view message), (override));
  MOCK_METHOD(void, OnHandshakeDoneReceived, (), (override));
  MOCK_METHOD(void, OnNewTokenReceived, (absl::string_view token), (override));
  MOCK_METHOD(void, OnConnectionClosed,
              (const QuicConnectionCloseFrame& frame,
               ConnectionCloseSource source),
              (override));
  MOCK_METHOD(void, OnWriteBlocked, (), (override));
  MOCK_METHOD(void, OnCanWrite, (), (override));
  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));
  MOCK_METHOD(void, OnConnectionMigration, (AddressChangeType type),
              (override));
  MOCK_METHOD(void, OnPathDegrading, (), (override));
  MOCK_METHOD(void, OnForwardProgressMadeAfterPathDegrading, (), (override));
  MOCK_METHOD(bool, WillingAndAbleToWrite, (), (const, override));
  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
  MOCK_METHOD(std::string, GetStreamsInfoForLogging, (), (const, override));
  MOCK_METHOD(void, OnSuccessfulVersionNegotiation,
              (const ParsedQuicVersion& version), (override));
  MOCK_METHOD(void, OnPacketReceived,
              (const QuicSocketAddress& self_address,
               const QuicSocketAddress& peer_address,
               bool is_connectivity_probe),
              (override));
  MOCK_METHOD(void, OnAckNeedsRetransmittableFrame, (), (override));
  MOCK_METHOD(void, SendAckFrequency, (const QuicAckFrequencyFrame& frame),
              (override));
  MOCK_METHOD(void, SendNewConnectionId,
              (const QuicNewConnectionIdFrame& frame), (override));
  MOCK_METHOD(void, SendRetireConnectionId, (uint64_t sequence_number),
              (override));
  MOCK_METHOD(bool, MaybeReserveConnectionId,
              (const QuicConnectionId& server_connection_id), (override));
  MOCK_METHOD(void, OnServerConnectionIdRetired,
              (const QuicConnectionId& server_connection_id), (override));
  MOCK_METHOD(bool, AllowSelfAddressChange, (), (const, override));
  MOCK_METHOD(HandshakeState, GetHandshakeState, (), (const, override));
  MOCK_METHOD(bool, OnMaxStreamsFrame, (const QuicMaxStreamsFrame& frame),
              (override));
  MOCK_METHOD(bool, OnStreamsBlockedFrame,
              (const QuicStreamsBlockedFrame& frame), (override));
  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
              (override));
  MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override));
  MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override));
  MOCK_METHOD(void, OnHandshakePacketSent, (), (override));
  MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override));
  MOCK_METHOD(std::unique_ptr<QuicDecrypter>,
              AdvanceKeysAndCreateCurrentOneRttDecrypter, (), (override));
  MOCK_METHOD(std::unique_ptr<QuicEncrypter>, CreateCurrentOneRttEncrypter, (),
              (override));
  MOCK_METHOD(void, BeforeConnectionCloseSent, (), (override));
  MOCK_METHOD(bool, ValidateToken, (absl::string_view), (override));
  MOCK_METHOD(bool, MaybeSendAddressToken, (), (override));

  bool IsKnownServerAddress(
      const QuicSocketAddress& /*address*/) const override {
    return false;
  }

  void OnBandwidthUpdateTimeout() override {}
};

class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
 public:
  MockQuicConnectionHelper();
  MockQuicConnectionHelper(const MockQuicConnectionHelper&) = delete;
  MockQuicConnectionHelper& operator=(const MockQuicConnectionHelper&) = delete;
  ~MockQuicConnectionHelper() override;
  const QuicClock* GetClock() const override;
  QuicRandom* GetRandomGenerator() override;
  quiche::QuicheBufferAllocator* GetStreamSendBufferAllocator() override;
  void AdvanceTime(QuicTime::Delta delta);

 private:
  MockClock clock_;
  MockRandom random_generator_;
  quiche::SimpleBufferAllocator buffer_allocator_;
};

class MockAlarmFactory : public QuicAlarmFactory {
 public:
  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
      QuicConnectionArena* arena) override;

  // No-op alarm implementation
  class TestAlarm : public QuicAlarm {
   public:
    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
        : QuicAlarm(std::move(delegate)) {}

    void SetImpl() override {}
    void CancelImpl() override {}

    using QuicAlarm::Fire;
  };

  void FireAlarm(QuicAlarm* alarm) {
    reinterpret_cast<TestAlarm*>(alarm)->Fire();
  }
};

class TestAlarmFactory : public QuicAlarmFactory {
 public:
  class TestAlarm : public QuicAlarm {
   public:
    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
        : QuicAlarm(std::move(delegate)) {}

    void SetImpl() override {}
    void CancelImpl() override {}
    using QuicAlarm::Fire;
  };

  TestAlarmFactory() {}
  TestAlarmFactory(const TestAlarmFactory&) = delete;
  TestAlarmFactory& operator=(const TestAlarmFactory&) = delete;

  QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
    return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
  }

  QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
      QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
      QuicConnectionArena* arena) override {
    return arena->New<TestAlarm>(std::move(delegate));
  }
};

class MockQuicConnection : public QuicConnection {
 public:
  // Uses a ConnectionId of 42 and 127.0.0.1:123.
  MockQuicConnection(MockQuicConnectionHelper* helper,
                     MockAlarmFactory* alarm_factory, Perspective perspective);

  // Uses a ConnectionId of 42.
  MockQuicConnection(QuicSocketAddress address,
                     MockQuicConnectionHelper* helper,
                     MockAlarmFactory* alarm_factory, Perspective perspective);

  // Uses 127.0.0.1:123.
  MockQuicConnection(QuicConnectionId connection_id,
                     MockQuicConnectionHelper* helper,
                     MockAlarmFactory* alarm_factory, Perspective perspective);

  // Uses a ConnectionId of 42, and 127.0.0.1:123.
  MockQuicConnection(MockQuicConnectionHelper* helper,
                     MockAlarmFactory* alarm_factory, Perspective perspective,
                     const ParsedQuicVersionVector& supported_versions);

  MockQuicConnection(QuicConnectionId connection_id, QuicSocketAddress address,
                     MockQuicConnectionHelper* helper,
                     MockAlarmFactory* alarm_factory, Perspective perspective,
                     const ParsedQuicVersionVector& supported_versions);
  MockQuicConnection(const MockQuicConnection&) = delete;
  MockQuicConnection& operator=(const MockQuicConnection&) = delete;

  ~MockQuicConnection() override;

  // If the constructor that uses a MockQuicConnectionHelper has been used then
  // this method
  // will advance the time of the MockClock.
  void AdvanceTime(QuicTime::Delta delta);

  MOCK_METHOD(void, ProcessUdpPacket,
              (const QuicSocketAddress& self_address,
               const QuicSocketAddress& peer_address,
               const QuicReceivedPacket& packet),
              (override));
  MOCK_METHOD(void, CloseConnection,
              (QuicErrorCode error, const std::string& details,
               ConnectionCloseBehavior connection_close_behavior),
              (override));
  MOCK_METHOD(void, CloseConnection,
              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
               const std::string& details,
               ConnectionCloseBehavior connection_close_behavior),
              (override));
  MOCK_METHOD(void, SendConnectionClosePacket,
              (QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
               const std::string& details),
              (override));
  MOCK_METHOD(void, OnCanWrite, (), (override));
  MOCK_METHOD(bool, SendConnectivityProbingPacket,
              (QuicPacketWriter*, const QuicSocketAddress& peer_address),
              (override));

  MOCK_METHOD(void, OnSendConnectionState, (const CachedNetworkParameters&),
              (override));
  MOCK_METHOD(void, ResumeConnectionState,
              (const CachedNetworkParameters&, bool), (override));
  MOCK_METHOD(void, SetMaxPacingRate, (QuicBandwidth), (override));

  MOCK_METHOD(void, OnStreamReset, (QuicStreamId, QuicRstStreamErrorCode),
              (override));
  MOCK_METHOD(bool, SendControlFrame, (const QuicFrame& frame), (override));
  MOCK_METHOD(MessageStatus, SendMessage,
              (QuicMessageId, absl::Span<quiche::QuicheMemSlice>, bool),
              (override));
  MOCK_METHOD(bool, SendPathChallenge,
              (const QuicPathFrameBuffer&, const QuicSocketAddress&,
               const QuicSocketAddress&, const QuicSocketAddress&,
               QuicPacketWriter*),
              (override));

  MOCK_METHOD(void, OnError, (QuicFramer*), (override));
  void QuicConnection_OnError(QuicFramer* framer) {
    QuicConnection::OnError(framer);
  }

  void ReallyOnCanWrite() { QuicConnection::OnCanWrite(); }

  void ReallyCloseConnection(
      QuicErrorCode error, const std::string& details,
      ConnectionCloseBehavior connection_close_behavior) {
    // Call the 4-param method directly instead of the 3-param method, so that
    // it doesn't invoke the virtual 4-param method causing the mock 4-param
    // method to trigger.
    QuicConnection::CloseConnection(error, NO_IETF_QUIC_ERROR, details,
                                    connection_close_behavior);
  }

  void ReallyCloseConnection4(
      QuicErrorCode error, QuicIetfTransportErrorCodes ietf_error,
      const std::string& details,
      ConnectionCloseBehavior connection_close_behavior) {
    QuicConnection::CloseConnection(error, ietf_error, details,
                                    connection_close_behavior);
  }

  void ReallySendConnectionClosePacket(QuicErrorCode error,
                                       QuicIetfTransportErrorCodes ietf_error,
                                       const std::string& details) {
    QuicConnection::SendConnectionClosePacket(error, ietf_error, details);
  }

  void ReallyProcessUdpPacket(const QuicSocketAddress& self_address,
                              const QuicSocketAddress& peer_address,
                              const QuicReceivedPacket& packet) {
    QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
  }

  bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;

  bool ReallySendControlFrame(const QuicFrame& frame) {
    return QuicConnection::SendControlFrame(frame);
  }

  bool ReallySendConnectivityProbingPacket(
      QuicPacketWriter* probing_writer, const QuicSocketAddress& peer_address) {
    return QuicConnection::SendConnectivityProbingPacket(probing_writer,
                                                         peer_address);
  }

  bool ReallyOnPathResponseFrame(const QuicPathResponseFrame& frame) {
    return QuicConnection::OnPathResponseFrame(frame);
  }

  MOCK_METHOD(bool, OnPathResponseFrame, (const QuicPathResponseFrame&),
              (override));
  MOCK_METHOD(bool, OnStopSendingFrame, (const QuicStopSendingFrame& frame),
              (override));
  MOCK_METHOD(size_t, SendCryptoData,
              (EncryptionLevel, size_t, QuicStreamOffset), (override));
  size_t QuicConnection_SendCryptoData(EncryptionLevel level,
                                       size_t write_length,
                                       QuicStreamOffset offset) {
    return QuicConnection::SendCryptoData(level, write_length, offset);
  }
};

class PacketSavingConnection : public MockQuicConnection {
 public:
  PacketSavingConnection(MockQuicConnectionHelper* helper,
                         MockAlarmFactory* alarm_factory,
                         Perspective perspective);

  PacketSavingConnection(MockQuicConnectionHelper* helper,
                         MockAlarmFactory* alarm_factory,
                         Perspective perspective,
                         const ParsedQuicVersionVector& supported_versions);
  PacketSavingConnection(const PacketSavingConnection&) = delete;
  PacketSavingConnection& operator=(const PacketSavingConnection&) = delete;

  ~PacketSavingConnection() override;

  SerializedPacketFate GetSerializedPacketFate(
      bool is_mtu_discovery, EncryptionLevel encryption_level) override;

  void SendOrQueuePacket(SerializedPacket packet) override;

  MOCK_METHOD(void, OnPacketSent, (EncryptionLevel, TransmissionType));

  std::vector<std::unique_ptr<QuicEncryptedPacket>> encrypted_packets_;
  // Number of packets in encrypted_packets that has been delivered to the peer
  // connection.
  size_t number_of_packets_delivered_ = 0;
  MockClock clock_;
};

class MockQuicSession : public QuicSession {
 public:
  // Takes ownership of |connection|.
  MockQuicSession(QuicConnection* connection, bool create_mock_crypto_stream);

  // Takes ownership of |connection|.
  explicit MockQuicSession(QuicConnection* connection);
  MockQuicSession(const MockQuicSession&) = delete;
  MockQuicSession& operator=(const MockQuicSession&) = delete;
  ~MockQuicSession() override;

  QuicCryptoStream* GetMutableCryptoStream() override;
  const QuicCryptoStream* GetCryptoStream() const override;
  void SetCryptoStream(QuicCryptoStream* crypto_stream);

  MOCK_METHOD(void, OnConnectionClosed,
              (const QuicConnectionCloseFrame& frame,
               ConnectionCloseSource source),
              (override));
  MOCK_METHOD(QuicStream*, CreateIncomingStream, (QuicStreamId id), (override));
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
              (override));
  MOCK_METHOD(QuicConsumedData, WritevData,
              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
               StreamSendingState state, TransmissionType type,
               EncryptionLevel level),
              (override));
  MOCK_METHOD(bool, WriteControlFrame,
              (const QuicFrame& frame, TransmissionType type), (override));
  MOCK_METHOD(void, MaybeSendRstStreamFrame,
              (QuicStreamId stream_id, QuicResetStreamError error,
               QuicStreamOffset bytes_written),
              (override));
  MOCK_METHOD(void, MaybeSendStopSendingFrame,
              (QuicStreamId stream_id, QuicResetStreamError error), (override));
  MOCK_METHOD(void, SendBlocked,
              (QuicStreamId stream_id, QuicStreamOffset offset), (override));

  MOCK_METHOD(bool, ShouldKeepConnectionAlive, (), (const, override));
  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
              (const std::vector<absl::string_view>&), (const, override));
  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));

  using QuicSession::ActivateStream;

  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
  // if set) has been consumed.
  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
                               QuicStreamOffset offset,
                               StreamSendingState state, TransmissionType type,
                               absl::optional<EncryptionLevel> level);

  void ReallyMaybeSendRstStreamFrame(QuicStreamId id,
                                     QuicRstStreamErrorCode error,
                                     QuicStreamOffset bytes_written) {
    QuicSession::MaybeSendRstStreamFrame(
        id, QuicResetStreamError::FromInternal(error), bytes_written);
  }

 private:
  std::unique_ptr<QuicCryptoStream> crypto_stream_;
};

class MockQuicCryptoStream : public QuicCryptoStream {
 public:
  explicit MockQuicCryptoStream(QuicSession* session);

  ~MockQuicCryptoStream() override;

  ssl_early_data_reason_t EarlyDataReason() const override;
  bool encryption_established() const override;
  bool one_rtt_keys_available() const override;
  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
      const override;
  CryptoMessageParser* crypto_message_parser() override;
  void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
  void OnOneRttPacketAcknowledged() override {}
  void OnHandshakePacketSent() override {}
  void OnHandshakeDoneReceived() override {}
  void OnNewTokenReceived(absl::string_view /*token*/) override {}
  std::string GetAddressToken(
      const CachedNetworkParameters* /*cached_network_parameters*/)
      const override {
    return "";
  }
  bool ValidateAddressToken(absl::string_view /*token*/) const override {
    return true;
  }
  const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
    return nullptr;
  }
  void SetPreviousCachedNetworkParams(
      CachedNetworkParameters /*cached_network_params*/) override {}
  void OnConnectionClosed(QuicErrorCode /*error*/,
                          ConnectionCloseSource /*source*/) override {}
  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
  void SetServerApplicationStateForResumption(
      std::unique_ptr<ApplicationState> /*application_state*/) override {}
  std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
      override {
    return nullptr;
  }
  std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
    return nullptr;
  }
  bool ExportKeyingMaterial(absl::string_view /*label*/,
                            absl::string_view /*context*/,
                            size_t /*result_len*/,
                            std::string* /*result*/) override {
    return false;
  }
  SSL* GetSsl() const override { return nullptr; }
  bool IsCryptoFrameExpectedForEncryptionLevel(
      quic::EncryptionLevel level) const override {
    return level != ENCRYPTION_ZERO_RTT;
  }
  EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
      PacketNumberSpace space) const override {
    switch (space) {
      case INITIAL_DATA:
        return ENCRYPTION_INITIAL;
      case HANDSHAKE_DATA:
        return ENCRYPTION_HANDSHAKE;
      case APPLICATION_DATA:
        return ENCRYPTION_FORWARD_SECURE;
      default:
        QUICHE_DCHECK(false);
        return NUM_ENCRYPTION_LEVELS;
    }
  }

 private:
  quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
  CryptoFramer crypto_framer_;
};

class MockQuicSpdySession : public QuicSpdySession {
 public:
  // Takes ownership of |connection|.
  explicit MockQuicSpdySession(QuicConnection* connection);
  // Takes ownership of |connection|.
  MockQuicSpdySession(QuicConnection* connection,
                      bool create_mock_crypto_stream);
  MockQuicSpdySession(const MockQuicSpdySession&) = delete;
  MockQuicSpdySession& operator=(const MockQuicSpdySession&) = delete;
  ~MockQuicSpdySession() override;

  QuicCryptoStream* GetMutableCryptoStream() override;
  const QuicCryptoStream* GetCryptoStream() const override;
  void SetCryptoStream(QuicCryptoStream* crypto_stream);

  void ReallyOnConnectionClosed(const QuicConnectionCloseFrame& frame,
                                ConnectionCloseSource source) {
    QuicSession::OnConnectionClosed(frame, source);
  }

  // From QuicSession.
  MOCK_METHOD(void, OnConnectionClosed,
              (const QuicConnectionCloseFrame& frame,
               ConnectionCloseSource source),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
              (override));
  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
  MOCK_METHOD(QuicConsumedData, WritevData,
              (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
               StreamSendingState state, TransmissionType type,
               EncryptionLevel level),
              (override));
  MOCK_METHOD(void, MaybeSendRstStreamFrame,
              (QuicStreamId stream_id, QuicResetStreamError error,
               QuicStreamOffset bytes_written),
              (override));
  MOCK_METHOD(void, MaybeSendStopSendingFrame,
              (QuicStreamId stream_id, QuicResetStreamError error), (override));
  MOCK_METHOD(void, SendWindowUpdate,
              (QuicStreamId id, QuicStreamOffset byte_offset), (override));
  MOCK_METHOD(void, SendBlocked,
              (QuicStreamId id, QuicStreamOffset byte_offset), (override));
  MOCK_METHOD(void, OnStreamHeadersPriority,
              (QuicStreamId stream_id,
               const spdy::SpdyStreamPrecedence& precedence),
              (override));
  MOCK_METHOD(void, OnStreamHeaderList,
              (QuicStreamId stream_id, bool fin, size_t frame_len,
               const QuicHeaderList& header_list),
              (override));
  MOCK_METHOD(void, OnPromiseHeaderList,
              (QuicStreamId stream_id, QuicStreamId promised_stream_id,
               size_t frame_len, const QuicHeaderList& header_list),
              (override));
  MOCK_METHOD(void, OnPriorityFrame,
              (QuicStreamId id, const spdy::SpdyStreamPrecedence& precedence),
              (override));
  MOCK_METHOD(void, OnCongestionWindowChange, (QuicTime now), (override));

  // Returns a QuicConsumedData that indicates all of |write_length| (and |fin|
  // if set) has been consumed.
  QuicConsumedData ConsumeData(QuicStreamId id, size_t write_length,
                               QuicStreamOffset offset,
                               StreamSendingState state, TransmissionType type,
                               absl::optional<EncryptionLevel> level);

  using QuicSession::ActivateStream;

 private:
  std::unique_ptr<QuicCryptoStream> crypto_stream_;
};

class MockHttp3DebugVisitor : public Http3DebugVisitor {
 public:
  MOCK_METHOD(void, OnControlStreamCreated, (QuicStreamId), (override));
  MOCK_METHOD(void, OnQpackEncoderStreamCreated, (QuicStreamId), (override));
  MOCK_METHOD(void, OnQpackDecoderStreamCreated, (QuicStreamId), (override));
  MOCK_METHOD(void, OnPeerControlStreamCreated, (QuicStreamId), (override));
  MOCK_METHOD(void, OnPeerQpackEncoderStreamCreated, (QuicStreamId),
              (override));
  MOCK_METHOD(void, OnPeerQpackDecoderStreamCreated, (QuicStreamId),
              (override));

  MOCK_METHOD(void, OnSettingsFrameReceivedViaAlps, (const SettingsFrame&),
              (override));

  MOCK_METHOD(void, OnAcceptChFrameReceivedViaAlps, (const AcceptChFrame&),
              (override));

  MOCK_METHOD(void, OnSettingsFrameReceived, (const SettingsFrame&),
              (override));
  MOCK_METHOD(void, OnGoAwayFrameReceived, (const GoAwayFrame&), (override));
  MOCK_METHOD(void, OnPriorityUpdateFrameReceived, (const PriorityUpdateFrame&),
              (override));
  MOCK_METHOD(void, OnAcceptChFrameReceived, (const AcceptChFrame&),
              (override));

  MOCK_METHOD(void, OnDataFrameReceived, (QuicStreamId, QuicByteCount),
              (override));
  MOCK_METHOD(void, OnHeadersFrameReceived, (QuicStreamId, QuicByteCount),
              (override));
  MOCK_METHOD(void, OnHeadersDecoded, (QuicStreamId, QuicHeaderList),
              (override));
  MOCK_METHOD(void, OnUnknownFrameReceived,
              (QuicStreamId, uint64_t, QuicByteCount), (override));

  MOCK_METHOD(void, OnSettingsFrameSent, (const SettingsFrame&), (override));
  MOCK_METHOD(void, OnGoAwayFrameSent, (QuicStreamId), (override));
  MOCK_METHOD(void, OnPriorityUpdateFrameSent, (const PriorityUpdateFrame&),
              (override));

  MOCK_METHOD(void, OnDataFrameSent, (QuicStreamId, QuicByteCount), (override));
  MOCK_METHOD(void, OnHeadersFrameSent,
              (QuicStreamId, const spdy::Http2HeaderBlock&), (override));
};

class TestQuicSpdyServerSession : public QuicServerSessionBase {
 public:
  // Takes ownership of |connection|.
  TestQuicSpdyServerSession(QuicConnection* connection,
                            const QuicConfig& config,
                            const ParsedQuicVersionVector& supported_versions,
                            const QuicCryptoServerConfig* crypto_config,
                            QuicCompressedCertsCache* compressed_certs_cache);
  TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
  TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
      delete;
  ~TestQuicSpdyServerSession() override;

  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
              (override));
  MOCK_METHOD(std::vector<absl::string_view>::const_iterator, SelectAlpn,
              (const std::vector<absl::string_view>&), (const, override));
  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
  std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
      const QuicCryptoServerConfig* crypto_config,
      QuicCompressedCertsCache* compressed_certs_cache) override;

  QuicCryptoServerStreamBase* GetMutableCryptoStream() override;

  const QuicCryptoServerStreamBase* GetCryptoStream() const override;

  MockQuicCryptoServerStreamHelper* helper() { return &helper_; }

  QuicSSLConfig GetSSLConfig() const override {
    QuicSSLConfig ssl_config = QuicServerSessionBase::GetSSLConfig();
    if (early_data_enabled_.has_value()) {
      ssl_config.early_data_enabled = *early_data_enabled_;
    }
    if (client_cert_mode_.has_value()) {
      ssl_config.client_cert_mode = *client_cert_mode_;
    }

    return ssl_config;
  }

  void set_early_data_enabled(bool enabled) { early_data_enabled_ = enabled; }

  void set_client_cert_mode(ClientCertMode mode) { client_cert_mode_ = mode; }

 private:
  MockQuicSessionVisitor visitor_;
  MockQuicCryptoServerStreamHelper helper_;
  // If not nullopt, override the early_data_enabled value from base class'
  // ssl_config.
  absl::optional<bool> early_data_enabled_;
  // If not nullopt, override the client_cert_mode value from base class'
  // ssl_config.
  absl::optional<ClientCertMode> client_cert_mode_;
};

// A test implementation of QuicClientPushPromiseIndex::Delegate.
class TestPushPromiseDelegate : public QuicClientPushPromiseIndex::Delegate {
 public:
  // |match| sets the validation result for checking whether designated header
  // fields match for promise request and client request.
  explicit TestPushPromiseDelegate(bool match);

  bool CheckVary(const spdy::Http2HeaderBlock& client_request,
                 const spdy::Http2HeaderBlock& promise_request,
                 const spdy::Http2HeaderBlock& promise_response) override;

  void OnRendezvousResult(QuicSpdyStream* stream) override;

  QuicSpdyStream* rendezvous_stream() { return rendezvous_stream_; }
  bool rendezvous_fired() { return rendezvous_fired_; }

 private:
  bool match_;
  bool rendezvous_fired_;
  QuicSpdyStream* rendezvous_stream_;
};

class TestQuicSpdyClientSession : public QuicSpdyClientSessionBase {
 public:
  TestQuicSpdyClientSession(QuicConnection* connection,
                            const QuicConfig& config,
                            const ParsedQuicVersionVector& supported_versions,
                            const QuicServerId& server_id,
                            QuicCryptoClientConfig* crypto_config);
  TestQuicSpdyClientSession(const TestQuicSpdyClientSession&) = delete;
  TestQuicSpdyClientSession& operator=(const TestQuicSpdyClientSession&) =
      delete;
  ~TestQuicSpdyClientSession() override;

  bool IsAuthorized(const std::string& authority) override;

  // QuicSpdyClientSessionBase
  MOCK_METHOD(void, OnProofValid,
              (const QuicCryptoClientConfig::CachedState& cached), (override));
  MOCK_METHOD(void, OnProofVerifyDetailsAvailable,
              (const ProofVerifyDetails& verify_details), (override));

  // TestQuicSpdyClientSession
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
              (override));
  MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
              (override));
  MOCK_METHOD(bool, ShouldCreateIncomingStream, (QuicStreamId id), (override));
  MOCK_METHOD(bool, ShouldCreateOutgoingBidirectionalStream, (), (override));
  MOCK_METHOD(bool, ShouldCreateOutgoingUnidirectionalStream, (), (override));
  MOCK_METHOD(std::vector<std::string>, GetAlpnsToOffer, (), (const, override));
  MOCK_METHOD(void, OnAlpnSelected, (absl::string_view), (override));
  MOCK_METHOD(void, OnConfigNegotiated, (), (override));

  QuicCryptoClientStream* GetMutableCryptoStream() override;
  const QuicCryptoClientStream* GetCryptoStream() const override;

  // Override to save sent crypto handshake messages.
  void OnCryptoHandshakeMessageSent(
      const CryptoHandshakeMessage& message) override {
    sent_crypto_handshake_messages_.push_back(message);
  }

  const std::vector<CryptoHandshakeMessage>& sent_crypto_handshake_messages()
      const {
    return sent_crypto_handshake_messages_;
  }

 private:
  // Calls the parent class's OnConfigNegotiated method. Used to set the default
  // mock behavior for OnConfigNegotiated.
  void RealOnConfigNegotiated();

  std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
  QuicClientPushPromiseIndex push_promise_index_;
  std::vector<CryptoHandshakeMessage> sent_crypto_handshake_messages_;
};

class MockPacketWriter : public QuicPacketWriter {
 public:
  MockPacketWriter();
  MockPacketWriter(const MockPacketWriter&) = delete;
  MockPacketWriter& operator=(const MockPacketWriter&) = delete;
  ~MockPacketWriter() override;

  MOCK_METHOD(WriteResult, WritePacket,
              (const char*, size_t buf_len, const QuicIpAddress& self_address,
               const QuicSocketAddress& peer_address, PerPacketOptions*),
              (override));
  MOCK_METHOD(bool, IsWriteBlocked, (), (const, override));
  MOCK_METHOD(void, SetWritable, (), (override));
  MOCK_METHOD(absl::optional<int>, MessageTooBigErrorCode, (),
              (const, override));
  MOCK_METHOD(QuicByteCount, GetMaxPacketSize,
              (const QuicSocketAddress& peer_address), (const, override));
  MOCK_METHOD(bool, SupportsReleaseTime, (), (const, override));
  MOCK_METHOD(bool, IsBatchMode, (), (const, override));
  MOCK_METHOD(QuicPacketBuffer, GetNextWriteLocation,
              (const QuicIpAddress& self_address,
               const QuicSocketAddress& peer_address),
              (override));
  MOCK_METHOD(WriteResult, Flush, (), (override));
};

class MockSendAlgorithm : public SendAlgorithmInterface {
 public:
  MockSendAlgorithm();
  MockSendAlgorithm(const MockSendAlgorithm&) = delete;
  MockSendAlgorithm& operator=(const MockSendAlgorithm&) = delete;
  ~MockSendAlgorithm() override;

  MOCK_METHOD(void, SetFromConfig,
              (const QuicConfig& config, Perspective perspective), (override));
  MOCK_METHOD(void, ApplyConnectionOptions,
              (const QuicTagVector& connection_options), (override));
  MOCK_METHOD(void, SetInitialCongestionWindowInPackets,
              (QuicPacketCount packets), (override));
  MOCK_METHOD(void, OnCongestionEvent,
              (bool rtt_updated, QuicByteCount bytes_in_flight,
               QuicTime event_time, const AckedPacketVector& acked_packets,
               const LostPacketVector& lost_packets),
              (override));
  MOCK_METHOD(void, OnPacketSent,
              (QuicTime, QuicByteCount, QuicPacketNumber, QuicByteCount,
               HasRetransmittableData),
              (override));
  MOCK_METHOD(void, OnPacketNeutered, (QuicPacketNumber), (override));
  MOCK_METHOD(void, OnRetransmissionTimeout, (bool), (override));
  MOCK_METHOD(void, OnConnectionMigration, (), (override));
  MOCK_METHOD(bool, CanSend, (QuicByteCount), (override));
  MOCK_METHOD(QuicBandwidth, PacingRate, (QuicByteCount), (const, override));
  MOCK_METHOD(QuicBandwidth, BandwidthEstimate, (), (const, override));
  MOCK_METHOD(bool, HasGoodBandwidthEstimateForResumption, (),
              (const, override));
  MOCK_METHOD(QuicByteCount, GetCongestionWindow, (), (const, override));
  MOCK_METHOD(std::string, GetDebugState, (), (const, override));
  MOCK_METHOD(bool, InSlowStart, (), (const, override));
  MOCK_METHOD(bool, InRecovery, (), (const, override));
  MOCK_METHOD(QuicByteCount, GetSlowStartThreshold, (), (const, override));
  MOCK_METHOD(CongestionControlType, GetCongestionControlType, (),
              (const, override));
  MOCK_METHOD(void, AdjustNetworkParameters, (const NetworkParams&),
              (override));
  MOCK_METHOD(void, OnApplicationLimited, (QuicByteCount), (override));
  MOCK_METHOD(void, PopulateConnectionStats, (QuicConnectionStats*),
              (const, override));
};

class MockLossAlgorithm : public LossDetectionInterface {
 public:
  MockLossAlgorithm();
  MockLossAlgorithm(const MockLossAlgorithm&) = delete;
  MockLossAlgorithm& operator=(const MockLossAlgorithm&) = delete;
  ~MockLossAlgorithm() override;

  MOCK_METHOD(void, SetFromConfig,
              (const QuicConfig& config, Perspective perspective), (override));

  MOCK_METHOD(DetectionStats, DetectLosses,
              (const QuicUnackedPacketMap& unacked_packets, QuicTime time,
               const RttStats& rtt_stats,
               QuicPacketNumber largest_recently_acked,
               const AckedPacketVector& packets_acked, LostPacketVector*),
              (override));
  MOCK_METHOD(QuicTime, GetLossTimeout, (), (const, override));
  MOCK_METHOD(void, SpuriousLossDetected,
              (const QuicUnackedPacketMap&, const RttStats&, QuicTime,
               QuicPacketNumber, QuicPacketNumber),
              (override));

  MOCK_METHOD(void, OnConfigNegotiated, (), (override));
  MOCK_METHOD(void, OnMinRttAvailable, (), (override));
  MOCK_METHOD(void, OnUserAgentIdKnown, (), (override));
  MOCK_METHOD(void, OnConnectionClosed, (), (override));
  MOCK_METHOD(void, OnReorderingDetected, (), (override));
};

class MockAckListener : public QuicAckListenerInterface {
 public:
  MockAckListener();
  MockAckListener(const MockAckListener&) = delete;
  MockAckListener& operator=(const MockAckListener&) = delete;

  MOCK_METHOD(void, OnPacketAcked,
              (int acked_bytes, QuicTime::Delta ack_delay_time), (override));

  MOCK_METHOD(void, OnPacketRetransmitted, (int retransmitted_bytes),
              (override));

 protected:
  // Object is ref counted.
  ~MockAckListener() override;
};

class MockNetworkChangeVisitor
    : public QuicSentPacketManager::NetworkChangeVisitor {
 public:
  MockNetworkChangeVisitor();
  MockNetworkChangeVisitor(const MockNetworkChangeVisitor&) = delete;
  MockNetworkChangeVisitor& operator=(const MockNetworkChangeVisitor&) = delete;
  ~MockNetworkChangeVisitor() override;

  MOCK_METHOD(void, OnCongestionChange, (), (override));
  MOCK_METHOD(void, OnPathMtuIncreased, (QuicPacketLength), (override));
};

class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
 public:
  MockQuicConnectionDebugVisitor();
  ~MockQuicConnectionDebugVisitor() override;

  MOCK_METHOD(void, OnPacketSent,
              (QuicPacketNumber, QuicPacketLength, bool, TransmissionType,
               EncryptionLevel, const QuicFrames&, const QuicFrames&, QuicTime),
              (override));

  MOCK_METHOD(void, OnCoalescedPacketSent, (const QuicCoalescedPacket&, size_t),
              (override));

  MOCK_METHOD(void, OnPingSent, (), (override));

  MOCK_METHOD(void, OnPacketReceived,
              (const QuicSocketAddress&, const QuicSocketAddress&,
               const QuicEncryptedPacket&),
              (override));

  MOCK_METHOD(void, OnIncorrectConnectionId, (QuicConnectionId), (override));

  MOCK_METHOD(void, OnProtocolVersionMismatch, (ParsedQuicVersion), (override));

  MOCK_METHOD(void, OnPacketHeader,
              (const QuicPacketHeader& header, QuicTime receive_time,
               EncryptionLevel level),
              (override));

  MOCK_METHOD(void, OnSuccessfulVersionNegotiation, (const ParsedQuicVersion&),
              (override));

  MOCK_METHOD(void, OnStreamFrame, (const QuicStreamFrame&), (override));

  MOCK_METHOD(void, OnCryptoFrame, (const QuicCryptoFrame&), (override));

  MOCK_METHOD(void, OnStopWaitingFrame, (const QuicStopWaitingFrame&),
              (override));

  MOCK_METHOD(void, OnRstStreamFrame, (const QuicRstStreamFrame&), (override));

  MOCK_METHOD(void, OnConnectionCloseFrame, (const QuicConnectionCloseFrame&),
              (override));

  MOCK_METHOD(void, OnBlockedFrame, (const QuicBlockedFrame&), (override));

  MOCK_METHOD(void, OnNewConnectionIdFrame, (const QuicNewConnectionIdFrame&),
              (override));

  MOCK_METHOD(void, OnRetireConnectionIdFrame,
              (const QuicRetireConnectionIdFrame&), (override));

  MOCK_METHOD(void, OnNewTokenFrame, (const QuicNewTokenFrame&), (override));

  MOCK_METHOD(void, OnMessageFrame, (const QuicMessageFrame&), (override));

  MOCK_METHOD(void, OnStopSendingFrame, (const QuicStopSendingFrame&),
              (override));

  MOCK_METHOD(void, OnPathChallengeFrame, (const QuicPathChallengeFrame&),
              (override));

  MOCK_METHOD(void, OnPathResponseFrame, (const QuicPathResponseFrame&),
              (override));

  MOCK_METHOD(void, OnPublicResetPacket, (const QuicPublicResetPacket&),
              (override));

  MOCK_METHOD(void, OnVersionNegotiationPacket,
              (const QuicVersionNegotiationPacket&), (override));

  MOCK_METHOD(void, OnTransportParametersSent, (const TransportParameters&),
              (override));

  MOCK_METHOD(void, OnTransportParametersReceived, (const TransportParameters&),
              (override));

  MOCK_METHOD(void, OnZeroRttRejected, (int), (override));
  MOCK_METHOD(void, OnZeroRttPacketAcked, (), (override));
};

class MockReceivedPacketManager : public QuicReceivedPacketManager {
 public:
  explicit MockReceivedPacketManager(QuicConnectionStats* stats);
  ~MockReceivedPacketManager() override;

  MOCK_METHOD(void, RecordPacketReceived,
              (const QuicPacketHeader& header, QuicTime receipt_time),
              (override));
  MOCK_METHOD(bool, IsMissing, (QuicPacketNumber packet_number), (override));
  MOCK_METHOD(bool, IsAwaitingPacket, (QuicPacketNumber packet_number),
              (const, override));
  MOCK_METHOD(bool, HasNewMissingPackets, (), (const, override));
  MOCK_METHOD(bool, ack_frame_updated, (), (const, override));
};

class MockPacketCreatorDelegate : public QuicPacketCreator::DelegateInterface {
 public:
  MockPacketCreatorDelegate();
  MockPacketCreatorDelegate(const MockPacketCreatorDelegate&) = delete;
  MockPacketCreatorDelegate& operator=(const MockPacketCreatorDelegate&) =
      delete;
  ~MockPacketCreatorDelegate() override;

  MOCK_METHOD(QuicPacketBuffer, GetPacketBuffer, (), (override));
  MOCK_METHOD(void, OnSerializedPacket, (SerializedPacket), (override));
  MOCK_METHOD(void, OnUnrecoverableError, (QuicErrorCode, const std::string&),
              (override));
  MOCK_METHOD(bool, ShouldGeneratePacket,
              (HasRetransmittableData retransmittable, IsHandshake handshake),
              (override));
  MOCK_METHOD(const QuicFrames, MaybeBundleAckOpportunistically, (),
              (override));
  MOCK_METHOD(SerializedPacketFate, GetSerializedPacketFate,
              (bool, EncryptionLevel), (override));
};

class MockSessionNotifier : public SessionNotifierInterface {
 public:
  MockSessionNotifier();
  ~MockSessionNotifier() override;

  MOCK_METHOD(bool, OnFrameAcked, (const QuicFrame&, QuicTime::Delta, QuicTime),
              (override));
  MOCK_METHOD(void, OnStreamFrameRetransmitted, (const QuicStreamFrame&),
              (override));
  MOCK_METHOD(void, OnFrameLost, (const QuicFrame&), (override));
  MOCK_METHOD(bool, RetransmitFrames,
              (const QuicFrames&, TransmissionType type), (override));
  MOCK_METHOD(bool, IsFrameOutstanding, (const QuicFrame&), (const, override));
  MOCK_METHOD(bool, HasUnackedCryptoData, (), (const, override));
  MOCK_METHOD(bool, HasUnackedStreamData, (), (const, override));
};

class MockQuicPathValidationContext : public QuicPathValidationContext {
 public:
  MockQuicPathValidationContext(const QuicSocketAddress& self_address,
                                const QuicSocketAddress& peer_address,
                                const QuicSocketAddress& effective_peer_address,
                                QuicPacketWriter* writer)
      : QuicPathValidationContext(self_address, peer_address,
                                  effective_peer_address),
        writer_(writer) {}
  QuicPacketWriter* WriterToUse() override { return writer_; }

 private:
  QuicPacketWriter* writer_;
};

class MockQuicPathValidationResultDelegate
    : public QuicPathValidator::ResultDelegate {
 public:
  MOCK_METHOD(void, OnPathValidationSuccess,
              (std::unique_ptr<QuicPathValidationContext>, QuicTime),
              (override));

  MOCK_METHOD(void, OnPathValidationFailure,
              (std::unique_ptr<QuicPathValidationContext>), (override));
};

class MockHttpDecoderVisitor : public HttpDecoder::Visitor {
 public:
  ~MockHttpDecoderVisitor() override = default;

  // Called if an error is detected.
  MOCK_METHOD(void, OnError, (HttpDecoder*), (override));

  MOCK_METHOD(bool, OnMaxPushIdFrame, (), (override));
  MOCK_METHOD(bool, OnGoAwayFrame, (const GoAwayFrame& frame), (override));
  MOCK_METHOD(bool, OnSettingsFrameStart, (QuicByteCount header_length),
              (override));
  MOCK_METHOD(bool, OnSettingsFrame, (const SettingsFrame& frame), (override));

  MOCK_METHOD(bool, OnDataFrameStart,
              (QuicByteCount header_length, QuicByteCount payload_length),
              (override));
  MOCK_METHOD(bool, OnDataFramePayload, (absl::string_view payload),
              (override));
  MOCK_METHOD(bool, OnDataFrameEnd, (), (override));

  MOCK_METHOD(bool, OnHeadersFrameStart,
              (QuicByteCount header_length, QuicByteCount payload_length),
              (override));
  MOCK_METHOD(bool, OnHeadersFramePayload, (absl::string_view payload),
              (override));
  MOCK_METHOD(bool, OnHeadersFrameEnd, (), (override));

  MOCK_METHOD(bool, OnPriorityUpdateFrameStart, (QuicByteCount header_length),
              (override));
  MOCK_METHOD(bool, OnPriorityUpdateFrame, (const PriorityUpdateFrame& frame),
              (override));

  MOCK_METHOD(bool, OnAcceptChFrameStart, (QuicByteCount header_length),
              (override));
  MOCK_METHOD(bool, OnAcceptChFrame, (const AcceptChFrame& frame), (override));
  MOCK_METHOD(void, OnWebTransportStreamFrameType,
              (QuicByteCount header_length, WebTransportSessionId session_id),
              (override));

  MOCK_METHOD(bool, OnUnknownFrameStart,
              (uint64_t frame_type, QuicByteCount header_length,
               QuicByteCount payload_length),
              (override));
  MOCK_METHOD(bool, OnUnknownFramePayload, (absl::string_view payload),
              (override));
  MOCK_METHOD(bool, OnUnknownFrameEnd, (), (override));
};

class QuicCryptoClientStreamPeer {
 public:
  QuicCryptoClientStreamPeer() = delete;

  static QuicCryptoClientStream::HandshakerInterface* GetHandshaker(
      QuicCryptoClientStream* stream);
};

// Creates a client session for testing.
//
// server_id: The server id associated with this stream.
// connection_start_time: The time to set for the connection clock.
//   Needed for strike-register nonce verification.  The client
//   connection_start_time should be synchronized witht the server
//   start time, otherwise nonce verification will fail.
// supported_versions: Set of QUIC versions this client supports.
// helper: Pointer to the MockQuicConnectionHelper to use for the session.
// crypto_client_config: Pointer to the crypto client config.
// client_connection: Pointer reference for newly created
//   connection.  This object will be owned by the
//   client_session.
// client_session: Pointer reference for the newly created client
//   session.  The new object will be owned by the caller.
void CreateClientSessionForTest(
    QuicServerId server_id, QuicTime::Delta connection_start_time,
    const ParsedQuicVersionVector& supported_versions,
    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
    QuicCryptoClientConfig* crypto_client_config,
    PacketSavingConnection** client_connection,
    TestQuicSpdyClientSession** client_session);

// Creates a server session for testing.
//
// server_id: The server id associated with this stream.
// connection_start_time: The time to set for the connection clock.
//   Needed for strike-register nonce verification.  The server
//   connection_start_time should be synchronized witht the client
//   start time, otherwise nonce verification will fail.
// supported_versions: Set of QUIC versions this server supports.
// helper: Pointer to the MockQuicConnectionHelper to use for the session.
// server_crypto_config: Pointer to the crypto server config.
// server_connection: Pointer reference for newly created
//   connection.  This object will be owned by the
//   server_session.
// server_session: Pointer reference for the newly created server
//   session.  The new object will be owned by the caller.
void CreateServerSessionForTest(
    QuicServerId server_id, QuicTime::Delta connection_start_time,
    ParsedQuicVersionVector supported_versions,
    MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
    QuicCryptoServerConfig* server_crypto_config,
    QuicCompressedCertsCache* compressed_certs_cache,
    PacketSavingConnection** server_connection,
    TestQuicSpdyServerSession** server_session);

// Verifies that the relative error of |actual| with respect to |expected| is
// no more than |margin|.
// Please use EXPECT_APPROX_EQ, a wrapper around this function, for better error
// report.
template <typename T>
void ExpectApproxEq(T expected, T actual, float relative_margin) {
  // If |relative_margin| > 1 and T is an unsigned type, the comparison will
  // underflow.
  ASSERT_LE(relative_margin, 1);
  ASSERT_GE(relative_margin, 0);

  T absolute_margin = expected * relative_margin;

  EXPECT_GE(expected + absolute_margin, actual) << "actual value too big";
  EXPECT_LE(expected - absolute_margin, actual) << "actual value too small";
}

#define EXPECT_APPROX_EQ(expected, actual, relative_margin)                    \
  do {                                                                         \
    SCOPED_TRACE(testing::Message() << "relative_margin:" << relative_margin); \
    quic::test::ExpectApproxEq(expected, actual, relative_margin);             \
  } while (0)

template <typename T>
QuicHeaderList AsHeaderList(const T& container) {
  QuicHeaderList l;
  l.OnHeaderBlockStart();
  size_t total_size = 0;
  for (auto p : container) {
    total_size += p.first.size() + p.second.size();
    l.OnHeader(p.first, p.second);
  }
  l.OnHeaderBlockEnd(total_size, total_size);
  return l;
}

// Helper functions for stream ids, to allow test logic to abstract over the
// HTTP stream numbering scheme (i.e. whether one or two QUIC streams are used
// per HTTP transaction).
QuicStreamId GetNthClientInitiatedBidirectionalStreamId(
    QuicTransportVersion version, int n);
QuicStreamId GetNthServerInitiatedBidirectionalStreamId(
    QuicTransportVersion version, int n);
QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(
    QuicTransportVersion version, int n);
QuicStreamId GetNthClientInitiatedUnidirectionalStreamId(
    QuicTransportVersion version, int n);

StreamType DetermineStreamType(QuicStreamId id, ParsedQuicVersion version,
                               Perspective perspective, bool is_incoming,
                               StreamType default_type);

// Creates a MemSlice using a singleton trivial buffer allocator.  Performs a
// copy.
quiche::QuicheMemSlice MemSliceFromString(absl::string_view data);

// Used to compare ReceivedPacketInfo.
MATCHER_P(ReceivedPacketInfoEquals, info, "") {
  return info.ToString() == arg.ToString();
}

MATCHER_P(ReceivedPacketInfoConnectionIdEquals, destination_connection_id, "") {
  return arg.destination_connection_id == destination_connection_id;
}

MATCHER_P2(InRange, min, max, "") { return arg >= min && arg <= max; }

// A GMock matcher that prints expected and actual QuicErrorCode strings
// upon failure.  Example usage:
// EXPECT_THAT(stream_->connection_error(), IsError(QUIC_INTERNAL_ERROR));
MATCHER_P(IsError, expected,
          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
                       QuicErrorCodeToString(expected))) {
  *result_listener << QuicErrorCodeToString(static_cast<QuicErrorCode>(arg));
  return arg == expected;
}

// Shorthand for IsError(QUIC_NO_ERROR).
// Example usage: EXPECT_THAT(stream_->connection_error(), IsQuicNoError());
MATCHER(IsQuicNoError,
        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
                     QuicErrorCodeToString(QUIC_NO_ERROR))) {
  *result_listener << QuicErrorCodeToString(arg);
  return arg == QUIC_NO_ERROR;
}

// A GMock matcher that prints expected and actual QuicRstStreamErrorCode
// strings upon failure.  Example usage:
// EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_INTERNAL_ERROR));
MATCHER_P(IsStreamError, expected,
          absl::StrCat(negation ? "isn't equal to " : "is equal to ",
                       QuicRstStreamErrorCodeToString(expected))) {
  *result_listener << QuicRstStreamErrorCodeToString(arg);
  return arg == expected;
}

// Shorthand for IsStreamError(QUIC_STREAM_NO_ERROR).  Example usage:
// EXPECT_THAT(stream_->stream_error(), IsQuicStreamNoError());
MATCHER(IsQuicStreamNoError,
        absl::StrCat(negation ? "isn't equal to " : "is equal to ",
                     QuicRstStreamErrorCodeToString(QUIC_STREAM_NO_ERROR))) {
  *result_listener << QuicRstStreamErrorCodeToString(arg);
  return arg == QUIC_STREAM_NO_ERROR;
}

// TaggingEncrypter appends kTagSize bytes of |tag| to the end of each message.
class TaggingEncrypter : public QuicEncrypter {
 public:
  explicit TaggingEncrypter(uint8_t tag) : tag_(tag) {}
  TaggingEncrypter(const TaggingEncrypter&) = delete;
  TaggingEncrypter& operator=(const TaggingEncrypter&) = delete;

  ~TaggingEncrypter() override {}

  // QuicEncrypter interface.
  bool SetKey(absl::string_view /*key*/) override { return true; }

  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
    return true;
  }

  bool SetIV(absl::string_view /*iv*/) override { return true; }

  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
    return true;
  }

  bool EncryptPacket(uint64_t packet_number, absl::string_view associated_data,
                     absl::string_view plaintext, char* output,
                     size_t* output_length, size_t max_output_length) override;

  std::string GenerateHeaderProtectionMask(
      absl::string_view /*sample*/) override {
    return std::string(5, 0);
  }

  size_t GetKeySize() const override { return 0; }
  size_t GetNoncePrefixSize() const override { return 0; }
  size_t GetIVSize() const override { return 0; }

  size_t GetMaxPlaintextSize(size_t ciphertext_size) const override {
    return ciphertext_size - kTagSize;
  }

  size_t GetCiphertextSize(size_t plaintext_size) const override {
    return plaintext_size + kTagSize;
  }

  QuicPacketCount GetConfidentialityLimit() const override {
    return std::numeric_limits<QuicPacketCount>::max();
  }

  absl::string_view GetKey() const override { return absl::string_view(); }

  absl::string_view GetNoncePrefix() const override {
    return absl::string_view();
  }

 private:
  enum {
    kTagSize = 12,
  };

  const uint8_t tag_;
};

// TaggingDecrypter ensures that the final kTagSize bytes of the message all
// have the same value and then removes them.
class TaggingDecrypter : public QuicDecrypter {
 public:
  ~TaggingDecrypter() override {}

  // QuicDecrypter interface
  bool SetKey(absl::string_view /*key*/) override { return true; }

  bool SetNoncePrefix(absl::string_view /*nonce_prefix*/) override {
    return true;
  }

  bool SetIV(absl::string_view /*iv*/) override { return true; }

  bool SetHeaderProtectionKey(absl::string_view /*key*/) override {
    return true;
  }

  bool SetPreliminaryKey(absl::string_view /*key*/) override {
    QUIC_BUG(quic_bug_10230_1) << "should not be called";
    return false;
  }

  bool SetDiversificationNonce(const DiversificationNonce& /*key*/) override {
    return true;
  }

  bool DecryptPacket(uint64_t packet_number, absl::string_view associated_data,
                     absl::string_view ciphertext, char* output,
                     size_t* output_length, size_t max_output_length) override;

  std::string GenerateHeaderProtectionMask(
      QuicDataReader* /*sample_reader*/) override {
    return std::string(5, 0);
  }

  size_t GetKeySize() const override { return 0; }
  size_t GetNoncePrefixSize() const override { return 0; }
  size_t GetIVSize() const override { return 0; }
  absl::string_view GetKey() const override { return absl::string_view(); }
  absl::string_view GetNoncePrefix() const override {
    return absl::string_view();
  }
  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
  uint32_t cipher_id() const override { return 0xFFFFFFF0; }
  QuicPacketCount GetIntegrityLimit() const override {
    return std::numeric_limits<QuicPacketCount>::max();
  }

 protected:
  virtual uint8_t GetTag(absl::string_view ciphertext) {
    return ciphertext.data()[ciphertext.size() - 1];
  }

 private:
  enum {
    kTagSize = 12,
  };

  bool CheckTag(absl::string_view ciphertext, uint8_t tag);
};

// StringTaggingDecrypter ensures that the final kTagSize bytes of the message
// match the expected value.
class StrictTaggingDecrypter : public TaggingDecrypter {
 public:
  explicit StrictTaggingDecrypter(uint8_t tag) : tag_(tag) {}
  ~StrictTaggingDecrypter() override {}

  // TaggingQuicDecrypter
  uint8_t GetTag(absl::string_view /*ciphertext*/) override { return tag_; }

  // Use a distinct value starting with 0xFFFFFF, which is never used by TLS.
  uint32_t cipher_id() const override { return 0xFFFFFFF1; }

 private:
  const uint8_t tag_;
};

class TestPacketWriter : public QuicPacketWriter {
  struct PacketBuffer {
    ABSL_CACHELINE_ALIGNED char buffer[1500];
    bool in_use = false;
  };

 public:
  TestPacketWriter(ParsedQuicVersion version, MockClock* clock,
                   Perspective perspective);

  TestPacketWriter(const TestPacketWriter&) = delete;
  TestPacketWriter& operator=(const TestPacketWriter&) = delete;

  ~TestPacketWriter() override;

  // QuicPacketWriter interface
  WriteResult WritePacket(const char* buffer, size_t buf_len,
                          const QuicIpAddress& self_address,
                          const QuicSocketAddress& peer_address,
                          PerPacketOptions* options) override;

  bool ShouldWriteFail() { return write_should_fail_; }

  bool IsWriteBlocked() const override { return write_blocked_; }

  absl::optional<int> MessageTooBigErrorCode() const override { return 0x1234; }

  void SetWriteBlocked() { write_blocked_ = true; }

  void SetWritable() override { write_blocked_ = false; }

  void SetShouldWriteFail() { write_should_fail_ = true; }

  void SetWriteError(int error_code) { write_error_code_ = error_code; }

  QuicByteCount GetMaxPacketSize(
      const QuicSocketAddress& /*peer_address*/) const override {
    return max_packet_size_;
  }

  bool SupportsReleaseTime() const override { return supports_release_time_; }

  bool IsBatchMode() const override { return is_batch_mode_; }

  QuicPacketBuffer GetNextWriteLocation(
      const QuicIpAddress& /*self_address*/,
      const QuicSocketAddress& /*peer_address*/) override;

  WriteResult Flush() override;

  void BlockOnNextFlush() { block_on_next_flush_ = true; }

  void BlockOnNextWrite() { block_on_next_write_ = true; }

  void SimulateNextPacketTooLarge() { next_packet_too_large_ = true; }

  void ExpectNextPacketUnprocessable() { next_packet_processable_ = false; }

  void AlwaysGetPacketTooLarge() { always_get_packet_too_large_ = true; }

  // Sets the amount of time that the writer should before the actual write.
  void SetWritePauseTimeDelta(QuicTime::Delta delta) {
    write_pause_time_delta_ = delta;
  }

  void SetBatchMode(bool new_value) { is_batch_mode_ = new_value; }

  const QuicPacketHeader& header() { return framer_.header(); }

  size_t frame_count() const { return framer_.num_frames(); }

  const std::vector<QuicAckFrame>& ack_frames() const {
    return framer_.ack_frames();
  }

  const std::vector<QuicStopWaitingFrame>& stop_waiting_frames() const {
    return framer_.stop_waiting_frames();
  }

  const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
    return framer_.connection_close_frames();
  }

  const std::vector<QuicRstStreamFrame>& rst_stream_frames() const {
    return framer_.rst_stream_frames();
  }

  const std::vector<std::unique_ptr<QuicStreamFrame>>& stream_frames() const {
    return framer_.stream_frames();
  }

  const std::vector<std::unique_ptr<QuicCryptoFrame>>& crypto_frames() const {
    return framer_.crypto_frames();
  }

  const std::vector<QuicPingFrame>& ping_frames() const {
    return framer_.ping_frames();
  }

  const std::vector<QuicMessageFrame>& message_frames() const {
    return framer_.message_frames();
  }

  const std::vector<QuicWindowUpdateFrame>& window_update_frames() const {
    return framer_.window_update_frames();
  }

  const std::vector<QuicPaddingFrame>& padding_frames() const {
    return framer_.padding_frames();
  }

  const std::vector<QuicPathChallengeFrame>& path_challenge_frames() const {
    return framer_.path_challenge_frames();
  }

  const std::vector<QuicPathResponseFrame>& path_response_frames() const {
    return framer_.path_response_frames();
  }

  const QuicEncryptedPacket* coalesced_packet() const {
    return framer_.coalesced_packet();
  }

  size_t last_packet_size() const { return last_packet_size_; }

  size_t total_bytes_written() const { return total_bytes_written_; }

  const QuicPacketHeader& last_packet_header() const {
    return last_packet_header_;
  }

  const QuicVersionNegotiationPacket* version_negotiation_packet() {
    return framer_.version_negotiation_packet();
  }

  void set_is_write_blocked_data_buffered(bool buffered) {
    is_write_blocked_data_buffered_ = buffered;
  }

  void set_perspective(Perspective perspective) {
    // We invert perspective here, because the framer needs to parse packets
    // we send.
    QuicFramerPeer::SetPerspective(framer_.framer(),
                                   QuicUtils::InvertPerspective(perspective));
    framer_.framer()->SetInitialObfuscators(TestConnectionId());
  }

  // final_bytes_of_last_packet_ returns the last four bytes of the previous
  // packet as a little-endian, uint32_t. This is intended to be used with a
  // TaggingEncrypter so that tests can determine which encrypter was used for
  // a given packet.
  uint32_t final_bytes_of_last_packet() { return final_bytes_of_last_packet_; }

  // Returns the final bytes of the second to last packet.
  uint32_t final_bytes_of_previous_packet() {
    return final_bytes_of_previous_packet_;
  }

  void use_tagging_decrypter() { use_tagging_decrypter_ = true; }

  uint32_t packets_write_attempts() const { return packets_write_attempts_; }

  uint32_t flush_attempts() const { return flush_attempts_; }

  uint32_t connection_close_packets() const {
    return connection_close_packets_;
  }

  void Reset() { framer_.Reset(); }

  void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
    framer_.SetSupportedVersions(versions);
  }

  void set_max_packet_size(QuicByteCount max_packet_size) {
    max_packet_size_ = max_packet_size;
  }

  void set_supports_release_time(bool supports_release_time) {
    supports_release_time_ = supports_release_time;
  }

  SimpleQuicFramer* framer() { return &framer_; }

  const QuicIpAddress& last_write_source_address() const {
    return last_write_source_address_;
  }

  const QuicSocketAddress& last_write_peer_address() const {
    return last_write_peer_address_;
  }

 private:
  char* AllocPacketBuffer();

  void FreePacketBuffer(const char* buffer);

  ParsedQuicVersion version_;
  SimpleQuicFramer framer_;
  size_t last_packet_size_ = 0;
  size_t total_bytes_written_ = 0;
  QuicPacketHeader last_packet_header_;
  bool write_blocked_ = false;
  bool write_should_fail_ = false;
  bool block_on_next_flush_ = false;
  bool block_on_next_write_ = false;
  bool next_packet_too_large_ = false;
  bool next_packet_processable_ = true;
  bool always_get_packet_too_large_ = false;
  bool is_write_blocked_data_buffered_ = false;
  bool is_batch_mode_ = false;
  // Number of times Flush() was called.
  uint32_t flush_attempts_ = 0;
  // (Batch mode only) Number of bytes buffered in writer. It is used as the
  // return value of a successful Flush().
  uint32_t bytes_buffered_ = 0;
  uint32_t final_bytes_of_last_packet_ = 0;
  uint32_t final_bytes_of_previous_packet_ = 0;
  bool use_tagging_decrypter_ = false;
  uint32_t packets_write_attempts_ = 0;
  uint32_t connection_close_packets_ = 0;
  MockClock* clock_ = nullptr;
  // If non-zero, the clock will pause during WritePacket for this amount of
  // time.
  QuicTime::Delta write_pause_time_delta_ = QuicTime::Delta::Zero();
  QuicByteCount max_packet_size_ = kMaxOutgoingPacketSize;
  bool supports_release_time_ = false;
  // Used to verify writer-allocated packet buffers are properly released.
  std::vector<PacketBuffer*> packet_buffer_pool_;
  // Buffer address => Address of the owning PacketBuffer.
  absl::flat_hash_map<char*, PacketBuffer*, absl::Hash<char*>>
      packet_buffer_pool_index_;
  // Indices in packet_buffer_pool_ that are not allocated.
  std::list<PacketBuffer*> packet_buffer_free_list_;
  // The soruce/peer address passed into WritePacket().
  QuicIpAddress last_write_source_address_;
  QuicSocketAddress last_write_peer_address_;
  int write_error_code_{0};
};

// Parses a packet generated by
// QuicFramer::WriteClientVersionNegotiationProbePacket.
// |packet_bytes| must point to |packet_length| bytes in memory which represent
// the packet. This method will fill in |destination_connection_id_bytes|
// which must point to at least |*destination_connection_id_length_out| bytes in
// memory. |*destination_connection_id_length_out| will contain the length of
// the received destination connection ID, which on success will match the
// contents of the destination connection ID passed in to
// WriteClientVersionNegotiationProbePacket.
bool ParseClientVersionNegotiationProbePacket(
    const char* packet_bytes, size_t packet_length,
    char* destination_connection_id_bytes,
    uint8_t* destination_connection_id_length_out);

// Writes an array of bytes that correspond to a QUIC version negotiation packet
// that a QUIC server would send in response to a probe created by
// QuicFramer::WriteClientVersionNegotiationProbePacket.
// The bytes will be written to |packet_bytes|, which must point to
// |*packet_length_out| bytes of memory. |*packet_length_out| will contain the
// length of the created packet. |source_connection_id_bytes| will be sent as
// the source connection ID, and must point to |source_connection_id_length|
// bytes of memory.
bool WriteServerVersionNegotiationProbeResponse(
    char* packet_bytes, size_t* packet_length_out,
    const char* source_connection_id_bytes,
    uint8_t source_connection_id_length);

// Implementation of Http3DatagramVisitor which saves all received datagrams.
class SavingHttp3DatagramVisitor : public QuicSpdyStream::Http3DatagramVisitor {
 public:
  struct SavedHttp3Datagram {
    QuicStreamId stream_id;
    std::string payload;
    bool operator==(const SavedHttp3Datagram& o) const {
      return stream_id == o.stream_id && payload == o.payload;
    }
  };
  const std::vector<SavedHttp3Datagram>& received_h3_datagrams() const {
    return received_h3_datagrams_;
  }

  // Override from QuicSpdyStream::Http3DatagramVisitor.
  void OnHttp3Datagram(QuicStreamId stream_id,
                       absl::string_view payload) override {
    received_h3_datagrams_.push_back(
        SavedHttp3Datagram{stream_id, std::string(payload)});
  }

 private:
  std::vector<SavedHttp3Datagram> received_h3_datagrams_;
};

inline std::string EscapeTestParamName(absl::string_view name) {
  std::string result(name);
  // Escape all characters that are not allowed by gtest ([a-zA-Z0-9_]).
  for (char& c : result) {
    bool valid = absl::ascii_isalnum(c) || c == '_';
    if (!valid) {
      c = '_';
    }
  }
  return result;
}

}  // namespace test
}  // namespace quic

#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
