// 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.

#include "quic/core/quic_crypto_stream.h"

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

#include "quic/core/crypto/crypto_handshake.h"
#include "quic/core/crypto/crypto_protocol.h"
#include "quic/core/crypto/null_encrypter.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_socket_address.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/crypto_test_utils.h"
#include "quic/test_tools/quic_stream_peer.h"
#include "quic/test_tools/quic_test_utils.h"

using testing::_;
using testing::InSequence;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Return;

namespace quic {
namespace test {
namespace {

class MockQuicCryptoStream : public QuicCryptoStream,
                             public QuicCryptoHandshaker {
 public:
  explicit MockQuicCryptoStream(QuicSession* session)
      : QuicCryptoStream(session),
        QuicCryptoHandshaker(this, session),
        params_(new QuicCryptoNegotiatedParameters) {}
  MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
  MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;

  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
    messages_.push_back(message);
  }

  std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }

  ssl_early_data_reason_t EarlyDataReason() const override {
    return ssl_early_data_unknown;
  }
  bool encryption_established() const override { return false; }
  bool one_rtt_keys_available() const override { return false; }

  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
      const override {
    return *params_;
  }
  CryptoMessageParser* crypto_message_parser() override {
    return QuicCryptoHandshaker::crypto_message_parser();
  }
  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 {}
  HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
  void SetServerApplicationStateForResumption(
      std::unique_ptr<ApplicationState> /*application_state*/) override {}
  bool KeyUpdateSupportedLocally() const override { return false; }
  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; }

 private:
  QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
  std::vector<CryptoHandshakeMessage> messages_;
};

class QuicCryptoStreamTest : public QuicTest {
 public:
  QuicCryptoStreamTest()
      : connection_(new MockQuicConnection(&helper_,
                                           &alarm_factory_,
                                           Perspective::IS_CLIENT)),
        session_(connection_, /*create_mock_crypto_stream=*/false) {
    stream_ = new MockQuicCryptoStream(&session_);
    session_.SetCryptoStream(stream_);
    session_.Initialize();
    message_.set_tag(kSHLO);
    message_.SetStringPiece(1, "abc");
    message_.SetStringPiece(2, "def");
    ConstructHandshakeMessage();
  }
  QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
  QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;

  void ConstructHandshakeMessage() {
    CryptoFramer framer;
    message_data_ = framer.ConstructHandshakeMessage(message_);
  }

 protected:
  MockQuicConnectionHelper helper_;
  MockAlarmFactory alarm_factory_;
  MockQuicConnection* connection_;
  MockQuicSpdySession session_;
  MockQuicCryptoStream* stream_;
  CryptoHandshakeMessage message_;
  std::unique_ptr<QuicData> message_data_;
};

TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
  EXPECT_FALSE(stream_->encryption_established());
  EXPECT_FALSE(stream_->one_rtt_keys_available());
}

TEST_F(QuicCryptoStreamTest, ProcessRawData) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    stream_->OnStreamFrame(QuicStreamFrame(
        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
        /*fin=*/false,
        /*offset=*/0, message_data_->AsStringPiece()));
  } else {
    stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
                                           message_data_->AsStringPiece()));
  }
  ASSERT_EQ(1u, stream_->messages()->size());
  const CryptoHandshakeMessage& message = (*stream_->messages())[0];
  EXPECT_EQ(kSHLO, message.tag());
  EXPECT_EQ(2u, message.tag_value_map().size());
  EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
  EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
}

TEST_F(QuicCryptoStreamTest, ProcessBadData) {
  std::string bad(message_data_->data(), message_data_->length());
  const int kFirstTagIndex = sizeof(uint32_t) +  // message tag
                             sizeof(uint16_t) +  // number of tag-value pairs
                             sizeof(uint16_t);   // padding
  EXPECT_EQ(1, bad[kFirstTagIndex]);
  bad[kFirstTagIndex] = 0x7F;  // out of order tag

  EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
                                            testing::_, testing::_));
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    stream_->OnStreamFrame(QuicStreamFrame(
        QuicUtils::GetCryptoStreamId(connection_->transport_version()),
        /*fin=*/false, /*offset=*/0, bad));
  } else {
    stream_->OnCryptoFrame(
        QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
  }
}

TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
  EXPECT_FALSE(
      QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
}

TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 0, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 1350, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Lost [0, 1000).
  stream_->OnStreamFrameLost(0, 1000, false);
  EXPECT_TRUE(stream_->HasPendingRetransmission());
  // Lost [1200, 2000).
  stream_->OnStreamFrameLost(1200, 800, false);
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1000, 0, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
  // they are in different encryption levels.
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 150, 1200, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 650, 1350, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->OnCanWrite();
  EXPECT_FALSE(stream_->HasPendingRetransmission());
  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
}

TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  std::unique_ptr<NullEncrypter> encrypter =
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
  connection_->SetEncrypter(
      ENCRYPTION_FORWARD_SECURE,
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Lost [0, 1000).
  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  // Lost [1200, 2000).
  lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
  stream_->OnCryptoFrameLost(&lost_frame);
  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
  // they are in different encryption levels.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WritePendingCryptoRetransmission();
  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
}

// Regression test for handling the missing ENCRYPTION_HANDSHAKE in
// quic_crypto_stream.cc. This test is essentially the same as
// RetransmitCryptoDataInCryptoFrames, except it uses ENCRYPTION_HANDSHAKE in
// place of ENCRYPTION_ZERO_RTT.
TEST_F(QuicCryptoStreamTest, RetransmitEncryptionHandshakeLevelCryptoFrames) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  InSequence s;
  // Send [0, 1000) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1000, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  // Send [1000, 2000) in ENCRYPTION_HANDSHAKE.
  std::unique_ptr<NullEncrypter> encrypter =
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
  connection_->SetEncrypter(ENCRYPTION_HANDSHAKE, std::move(encrypter));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
  EXPECT_EQ(ENCRYPTION_HANDSHAKE, connection_->encryption_level());
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 1000, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_HANDSHAKE, data);
  connection_->SetEncrypter(
      ENCRYPTION_FORWARD_SECURE,
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Lost [1000, 1200).
  QuicCryptoFrame lost_frame(ENCRYPTION_HANDSHAKE, 0, 200);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  // Verify [1000, 1200) is sent.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_HANDSHAKE, 200, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WritePendingCryptoRetransmission();
  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
}

TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 0, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 1350, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);

  // Lost [0, 1350).
  stream_->OnStreamFrameLost(0, 1350, false);
  EXPECT_TRUE(stream_->HasPendingRetransmission());
  // Neuters [0, 1350).
  stream_->NeuterUnencryptedStreamData();
  EXPECT_FALSE(stream_->HasPendingRetransmission());
  // Lost [0, 1350) again.
  stream_->OnStreamFrameLost(0, 1350, false);
  EXPECT_FALSE(stream_->HasPendingRetransmission());

  // Lost [1350, 2000).
  stream_->OnStreamFrameLost(1350, 650, false);
  EXPECT_TRUE(stream_->HasPendingRetransmission());
  stream_->NeuterUnencryptedStreamData();
  EXPECT_TRUE(stream_->HasPendingRetransmission());
}

TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  connection_->SetEncrypter(
      ENCRYPTION_ZERO_RTT,
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  std::unique_ptr<NullEncrypter> encrypter =
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);

  // Lost [0, 1350).
  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  // Neuters [0, 1350).
  stream_->NeuterUnencryptedStreamData();
  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
  // Lost [0, 1350) again.
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());

  // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
  // level.
  lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  stream_->NeuterUnencryptedStreamData();
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
}

TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 0, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 1350, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->WriteOrBufferData(data, false, nullptr);
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Ack [2000, 2500).
  QuicByteCount newly_acked_length = 0;
  stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
                              QuicTime::Zero(), &newly_acked_length);
  EXPECT_EQ(500u, newly_acked_length);

  // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 650, 1350, _, _, _))
      .WillOnce(InvokeWithoutArgs([this]() {
        return session_.ConsumeData(
            QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
            1350, NO_FIN, HANDSHAKE_RETRANSMISSION, absl::nullopt);
      }));

  EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false,
                                             HANDSHAKE_RETRANSMISSION));
  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Force session to send [1350, 1500) again and all data is consumed.
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 650, 1350, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 200, 2500, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false,
                                            HANDSHAKE_RETRANSMISSION));
  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
  // Force to send an empty frame.
  EXPECT_TRUE(
      stream_->RetransmitStreamData(0, 0, false, HANDSHAKE_RETRANSMISSION));
}

TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
  std::unique_ptr<NullEncrypter> encrypter =
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
  connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
  connection_->SetEncrypter(
      ENCRYPTION_FORWARD_SECURE,
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Ack [2000, 2500).
  QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
  EXPECT_TRUE(
      stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));

  // Retransmit only [1350, 1500).
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);

  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  // Retransmit [1350, 2700) again and all data is sent.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
  stream_->RetransmitData(&frame_to_retransmit, HANDSHAKE_RETRANSMISSION);
  // Verify connection's encryption level has restored.
  EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());

  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  // Force to send an empty frame.
  QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
  stream_->RetransmitData(&empty_frame, HANDSHAKE_RETRANSMISSION);
}

// Regression test for b/115926584.
TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  std::string data(1350, 'a');
  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 0, _, _, _))
      .WillOnce(testing::Return(QuicConsumedData(0, false)));
  stream_->WriteOrBufferData(data, false, nullptr);
  EXPECT_FALSE(stream_->IsWaitingForAcks());
  // Although there is no outstanding data, verify session has pending crypto
  // data.
  EXPECT_TRUE(session_.HasUnackedCryptoData());

  EXPECT_CALL(
      session_,
      WritevData(QuicUtils::GetCryptoStreamId(connection_->transport_version()),
                 1350, 0, _, _, _))
      .WillOnce(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
  stream_->OnCanWrite();
  EXPECT_TRUE(stream_->IsWaitingForAcks());
  EXPECT_TRUE(session_.HasUnackedCryptoData());
}

TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  EXPECT_TRUE(stream_->IsWaitingForAcks());
  EXPECT_TRUE(session_.HasUnackedCryptoData());
}

// Regression test for bugfix of GetPacketHeaderSize.
TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
  for (const ParsedQuicVersion& version :
       AllSupportedVersionsWithQuicCrypto()) {
    SCOPED_TRACE(version);
    QuicByteCount expected_overhead = 48;
    if (version.HasIetfInvariantHeader()) {
      expected_overhead += 4;
    }
    if (version.HasLongHeaderLengths()) {
      expected_overhead += 3;
    }
    if (version.HasLengthPrefixedConnectionIds()) {
      expected_overhead += 1;
    }
    EXPECT_EQ(expected_overhead,
              QuicCryptoStream::CryptoMessageFramingOverhead(
                  version.transport_version, TestConnectionId()));
  }
}

TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  // Only consumed 1000 bytes.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Return(1000));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());

  // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
  // because there is buffered data.
  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  connection_->SetEncrypter(
      ENCRYPTION_ZERO_RTT,
      std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
  connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
  stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());

  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
      .WillOnce(Return(350));
  // Partial write of ENCRYPTION_ZERO_RTT data.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
      .WillOnce(Return(1000));
  stream_->WriteBufferedCryptoFrames();
  EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
  EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());

  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
      .WillOnce(Return(350));
  stream_->WriteBufferedCryptoFrames();
  EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
}

TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }

  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
  std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
                          'a');

  // Set offset to 1 so that we guarantee the data gets buffered instead of
  // immediately processed.
  QuicStreamOffset offset = 1;
  stream_->OnCryptoFrame(
      QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
}

TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }

  EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
  InSequence s;
  // Send [0, 1350) in ENCRYPTION_INITIAL.
  EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
  std::string data(1350, 'a');
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);

  // Lost [0, 1000).
  QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
  stream_->OnCryptoFrameLost(&lost_frame);
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  // Simulate connection is constrained by amplification restriction.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
      .WillOnce(Return(0));
  stream_->WritePendingCryptoRetransmission();
  EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
  // Connection gets unblocked.
  EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
      .WillOnce(Invoke(connection_,
                       &MockQuicConnection::QuicConnection_SendCryptoData));
  stream_->WritePendingCryptoRetransmission();
  EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
}

// Regression test for b/203199510
TEST_F(QuicCryptoStreamTest, EmptyCryptoFrame) {
  if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
    return;
  }
  if (GetQuicReloadableFlag(quic_accept_empty_crypto_frame)) {
    EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
  } else {
    EXPECT_CALL(*connection_,
                CloseConnection(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _, _));
  }
  QuicCryptoFrame empty_crypto_frame(ENCRYPTION_INITIAL, 0, nullptr, 0);
  stream_->OnCryptoFrame(empty_crypto_frame);
}

}  // namespace
}  // namespace test
}  // namespace quic
