// 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 "net/quic/quic_packet_generator.h"

#include <string>

#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/quic_packet_creator_peer.h"
#include "net/quic/test_tools/quic_packet_generator_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/simple_quic_framer.h"
#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::StringPiece;
using std::string;
using std::vector;
using testing::InSequence;
using testing::Return;
using testing::StrictMock;
using testing::_;

namespace net {
namespace test {
namespace {

const int64 kMinFecTimeoutMs = 5u;

static const FecSendPolicy kFecSendPolicyList[] = {
    FEC_ANY_TRIGGER,
    FEC_ALARM_TRIGGER,
};

class MockDelegate : public QuicPacketGenerator::DelegateInterface {
 public:
  MockDelegate() {}
  ~MockDelegate() override {}

  MOCK_METHOD2(ShouldGeneratePacket,
               bool(HasRetransmittableData retransmittable,
                    IsHandshake handshake));
  MOCK_METHOD1(PopulateAckFrame, void(QuicAckFrame*));
  MOCK_METHOD1(PopulateStopWaitingFrame, void(QuicStopWaitingFrame*));
  MOCK_METHOD1(OnSerializedPacket, void(const SerializedPacket& packet));
  MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool));
  MOCK_METHOD0(OnResetFecGroup, void());

  void SetCanWriteAnything() {
    EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true));
    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
        .WillRepeatedly(Return(true));
  }

  void SetCanNotWrite() {
    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
        .WillRepeatedly(Return(false));
  }

  // Use this when only ack frames should be allowed to be written.
  void SetCanWriteOnlyNonRetransmittable() {
    EXPECT_CALL(*this, ShouldGeneratePacket(_, _))
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _))
        .WillRepeatedly(Return(true));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
};

// Simple struct for describing the contents of a packet.
// Useful in conjunction with a SimpleQuicFrame for validating that a packet
// contains the expected frames.
struct PacketContents {
  PacketContents()
      : num_ack_frames(0),
        num_connection_close_frames(0),
        num_goaway_frames(0),
        num_rst_stream_frames(0),
        num_stop_waiting_frames(0),
        num_stream_frames(0),
        num_ping_frames(0),
        num_mtu_discovery_frames(0),
        fec_group(0) {}

  size_t num_ack_frames;
  size_t num_connection_close_frames;
  size_t num_goaway_frames;
  size_t num_rst_stream_frames;
  size_t num_stop_waiting_frames;
  size_t num_stream_frames;
  size_t num_ping_frames;
  size_t num_mtu_discovery_frames;

  QuicFecGroupNumber fec_group;
};

}  // namespace

class QuicPacketGeneratorTest : public ::testing::TestWithParam<FecSendPolicy> {
 public:
  QuicPacketGeneratorTest()
      : framer_(QuicSupportedVersions(),
                QuicTime::Zero(),
                Perspective::IS_CLIENT),
        generator_(42, &framer_, &random_, &delegate_),
        creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)) {
    generator_.set_fec_send_policy(GetParam());
  }

  ~QuicPacketGeneratorTest() override {
    for (SerializedPacket& packet : packets_) {
      delete packet.packet;
      delete packet.retransmittable_frames;
    }
  }

  void SavePacket(const SerializedPacket& packet) {
    packets_.push_back(packet);
    ASSERT_FALSE(packet.packet->owns_buffer());
    scoped_ptr<QuicEncryptedPacket> encrypted_deleter(packets_.back().packet);
    packets_.back().packet = packets_.back().packet->Clone();
  }

 protected:
  QuicRstStreamFrame* CreateRstStreamFrame() {
    return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR, 0);
  }

  QuicGoAwayFrame* CreateGoAwayFrame() {
    return new QuicGoAwayFrame(QUIC_NO_ERROR, 1, string());
  }

  void CheckPacketContains(const PacketContents& contents,
                           size_t packet_index) {
    ASSERT_GT(packets_.size(), packet_index);
    const SerializedPacket& packet = packets_[packet_index];
    size_t num_retransmittable_frames =
        contents.num_connection_close_frames + contents.num_goaway_frames +
        contents.num_rst_stream_frames + contents.num_stream_frames +
        contents.num_ping_frames;
    size_t num_frames =
        contents.num_ack_frames + contents.num_stop_waiting_frames +
        contents.num_mtu_discovery_frames + num_retransmittable_frames;

    if (num_retransmittable_frames == 0) {
      ASSERT_TRUE(packet.retransmittable_frames == nullptr);
    } else {
      ASSERT_TRUE(packet.retransmittable_frames != nullptr);
      EXPECT_EQ(num_retransmittable_frames,
                packet.retransmittable_frames->frames().size());
    }

    ASSERT_TRUE(packet.packet != nullptr);
    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
    EXPECT_EQ(num_frames, simple_framer_.num_frames());
    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
    EXPECT_EQ(contents.num_connection_close_frames,
              simple_framer_.connection_close_frames().size());
    EXPECT_EQ(contents.num_goaway_frames,
              simple_framer_.goaway_frames().size());
    EXPECT_EQ(contents.num_rst_stream_frames,
              simple_framer_.rst_stream_frames().size());
    EXPECT_EQ(contents.num_stream_frames,
              simple_framer_.stream_frames().size());
    EXPECT_EQ(contents.num_stop_waiting_frames,
              simple_framer_.stop_waiting_frames().size());
    EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);

    // From the receiver's perspective, MTU discovery frames are ping frames.
    EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames,
              simple_framer_.ping_frames().size());
  }

  void CheckPacketHasSingleStreamFrame(size_t packet_index) {
    ASSERT_GT(packets_.size(), packet_index);
    const SerializedPacket& packet = packets_[packet_index];
    ASSERT_TRUE(packet.retransmittable_frames != nullptr);
    EXPECT_EQ(1u, packet.retransmittable_frames->frames().size());
    ASSERT_TRUE(packet.packet != nullptr);
    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
    EXPECT_EQ(1u, simple_framer_.num_frames());
    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
  }

  void CheckAllPacketsHaveSingleStreamFrame() {
    for (size_t i = 0; i < packets_.size(); i++) {
      CheckPacketHasSingleStreamFrame(i);
    }
  }

  void CheckPacketIsFec(size_t packet_index,
                        QuicPacketSequenceNumber fec_group) {
    ASSERT_GT(packets_.size(), packet_index);
    const SerializedPacket& packet = packets_[packet_index];
    ASSERT_TRUE(packet.retransmittable_frames == nullptr);
    ASSERT_TRUE(packet.packet != nullptr);
    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
    EXPECT_TRUE(simple_framer_.header().fec_flag);
    EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
  }

  QuicIOVector CreateData(size_t len) {
    data_array_.reset(new char[len]);
    memset(data_array_.get(), '?', len);
    iov_.iov_base = data_array_.get();
    iov_.iov_len = len;
    return QuicIOVector(&iov_, 1, len);
  }

  QuicIOVector MakeIOVector(StringPiece s) {
    return ::net::MakeIOVector(s, &iov_);
  }

  QuicFramer framer_;
  MockRandom random_;
  StrictMock<MockDelegate> delegate_;
  QuicPacketGenerator generator_;
  QuicPacketCreator* creator_;
  SimpleQuicFramer simple_framer_;
  vector<SerializedPacket> packets_;

 private:
  scoped_ptr<char[]> data_array_;
  struct iovec iov_;
};

class MockDebugDelegate : public QuicPacketGenerator::DebugDelegate {
 public:
  MOCK_METHOD1(OnFrameAddedToPacket,
               void(const QuicFrame&));
};

// Run all end to end tests with all supported FEC send polocies.
INSTANTIATE_TEST_CASE_P(FecSendPolicy,
                        QuicPacketGeneratorTest,
                        ::testing::ValuesIn(kFecSendPolicyList));

TEST_P(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
  delegate_.SetCanNotWrite();

  generator_.SetShouldSendAck(false);
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
  StrictMock<MockDebugDelegate> debug_delegate;

  generator_.set_debug_delegate(&debug_delegate);
  delegate_.SetCanWriteOnlyNonRetransmittable();
  generator_.StartBatchOperations();

  EXPECT_CALL(delegate_, PopulateAckFrame(_));
  EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1);

  generator_.SetShouldSendAck(false);
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
  delegate_.SetCanWriteOnlyNonRetransmittable();

  EXPECT_CALL(delegate_, PopulateAckFrame(_));
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  generator_.SetShouldSendAck(false);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_ack_frames = 1;
  CheckPacketContains(contents, 0);
}

TEST_P(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) {
  // Make sure that calling SetShouldSendAck multiple times does not result in a
  // crash. Previously this would result in multiple QuicFrames queued in the
  // packet generator, with all but the last with internal pointers to freed
  // memory.
  delegate_.SetCanWriteAnything();

  // Only one AckFrame should be created.
  EXPECT_CALL(delegate_, PopulateAckFrame(_)).Times(1);
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .Times(1)
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  generator_.StartBatchOperations();
  generator_.SetShouldSendAck(false);
  generator_.SetShouldSendAck(false);
  generator_.FinishBatchOperations();
}

TEST_P(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
  delegate_.SetCanNotWrite();

  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
  delegate_.SetCanWriteOnlyNonRetransmittable();

  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
  delegate_.SetCanNotWrite();
  generator_.StartBatchOperations();

  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());
  generator_.FinishBatchOperations();
  EXPECT_TRUE(generator_.HasQueuedFrames());

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.FlushAllQueuedFrames();
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_rst_stream_frames = 1;
  CheckPacketContains(contents, 0);
}

TEST_P(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
  delegate_.SetCanWriteAnything();

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_rst_stream_frames = 1;
  CheckPacketContains(contents, 0);
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
  delegate_.SetCanNotWrite();

  QuicConsumedData consumed = generator_.ConsumeData(
      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(0u, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  QuicConsumedData consumed = generator_.ConsumeData(
      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(3u, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
  delegate_.SetCanWriteAnything();

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(
      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(3u, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);
}

// Test the behavior of ConsumeData when the data consumed is for the crypto
// handshake stream.  Ensure that the packet is always sent and padded even if
// the generator operates in batch mode.
TEST_P(QuicPacketGeneratorTest, ConsumeData_Handshake) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(
      kCryptoStreamId, MakeIOVector("foo"), 0, false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(3u, consumed.bytes_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);

  ASSERT_EQ(1u, packets_.size());
  ASSERT_EQ(kDefaultMaxPacketSize, generator_.GetMaxPacketLength());
  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].packet->length());
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_EmptyData) {
  EXPECT_DFATAL(generator_.ConsumeData(kHeadersStreamId, MakeIOVector(""), 0,
                                       false, MAY_FEC_PROTECT, nullptr),
                "Attempt to consume empty data without FIN.");
}

TEST_P(QuicPacketGeneratorTest,
       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
                         MAY_FEC_PROTECT, nullptr);
  QuicConsumedData consumed = generator_.ConsumeData(
      3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(4u, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
                         MAY_FEC_PROTECT, nullptr);
  QuicConsumedData consumed = generator_.ConsumeData(
      3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(4u, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // Now both frames will be flushed out.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.FinishBatchOperations();
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_stream_frames = 2;
  CheckPacketContains(contents, 0);
}

TEST_P(QuicPacketGeneratorTest, ConsumeDataFecOnMaxGroupSize) {
  delegate_.SetCanWriteAnything();

  // Send FEC every two packets.
  creator_->set_max_packets_per_fec_group(2);

  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER, but FEC
      // group is closed.
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }

  // Send enough data to create 3 packets: two full and one partial. Send with
  // MUST_FEC_PROTECT flag.
  size_t data_len = 2 * kDefaultMaxPacketSize + 100;
  QuicConsumedData consumed = generator_.ConsumeData(
      3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  CheckPacketHasSingleStreamFrame(0);
  CheckPacketHasSingleStreamFrame(1);
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER.
    CheckPacketHasSingleStreamFrame(2);
  } else {
    CheckPacketIsFec(2, 1);
    CheckPacketHasSingleStreamFrame(3);
  }
  EXPECT_TRUE(creator_->IsFecProtected());

  // If FEC send policy is FEC_ANY_TRIGGER, then the FEC packet under
  // construction will be sent when one more packet is sent (since FEC group
  // size is 2), or when OnFecTimeout is called. Send more data with
  // MAY_FEC_PROTECT. This packet should also be protected, and FEC packet is
  // sent since FEC group size is reached.
  //
  // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed when the group
  // size is reached. FEC packet is not sent.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
  }
  consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    CheckPacketHasSingleStreamFrame(3);
  } else {
    CheckPacketHasSingleStreamFrame(4);
    CheckPacketIsFec(5, 4);
  }
  EXPECT_FALSE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(1000);

  // Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the
  // creator FEC protects all data.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(3, CreateData(1u), 0, true,
                                                     MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  CheckPacketHasSingleStreamFrame(0);
  EXPECT_TRUE(creator_->IsFecProtected());

  // Send more data with MAY_FEC_PROTECT. This packet should also be protected,
  // and FEC packet is not yet sent.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  CheckPacketHasSingleStreamFrame(1);
  EXPECT_TRUE(creator_->IsFecProtected());

  // Calling OnFecTimeout should cause the FEC packet to be emitted.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  CheckPacketIsFec(2, 1);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Subsequent data is protected under the next FEC group. Send enough data to
  // create 2 more packets: one full and one partial.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  size_t data_len = kDefaultMaxPacketSize + 1;
  consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  CheckPacketHasSingleStreamFrame(3);
  CheckPacketHasSingleStreamFrame(4);
  EXPECT_TRUE(creator_->IsFecProtected());

  // Calling OnFecTimeout should cause the FEC packet to be emitted.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  CheckPacketIsFec(5, 4);
  EXPECT_FALSE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(6);

  // Send enough data to create 2 packets: one full and one partial. Send with
  // MUST_FEC_PROTECT flag. No FEC packet is emitted yet, but the creator FEC
  // protects all data.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  size_t data_len = 1 * kDefaultMaxPacketSize + 100;
  QuicConsumedData consumed = generator_.ConsumeData(
      3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
  CheckPacketHasSingleStreamFrame(0);
  CheckPacketHasSingleStreamFrame(1);
  EXPECT_TRUE(creator_->IsFecProtected());

  // GetFecTimeout returns finite timeout only for first packet in group.
  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
            generator_.GetFecTimeout(/*sequence_number=*/1u));
  EXPECT_EQ(QuicTime::Delta::Infinite(),
            generator_.GetFecTimeout(/*sequence_number=*/2u));

  // Send more data with MAY_FEC_PROTECT. This packet should also be protected,
  // and FEC packet is not yet sent.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  CheckPacketHasSingleStreamFrame(2);
  EXPECT_TRUE(creator_->IsFecProtected());

  // GetFecTimeout returns finite timeout only for first packet in group.
  EXPECT_EQ(QuicTime::Delta::Infinite(),
            generator_.GetFecTimeout(/*sequence_number=*/3u));

  // Calling OnFecTimeout should cause the FEC packet to be emitted.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  CheckPacketIsFec(3, /*fec_group=*/1u);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Subsequent data is protected under the next FEC group. Send enough data to
  // create 2 more packets: one full and one partial.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  data_len = kDefaultMaxPacketSize + 1u;
  consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  CheckPacketHasSingleStreamFrame(4);
  CheckPacketHasSingleStreamFrame(5);
  EXPECT_TRUE(creator_->IsFecProtected());

  // GetFecTimeout returns finite timeout for first packet in the new group.
  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs),
            generator_.GetFecTimeout(/*sequence_number=*/5u));
  EXPECT_EQ(QuicTime::Delta::Infinite(),
            generator_.GetFecTimeout(/*sequence_number=*/6u));

  // Calling OnFecTimeout should cause the FEC packet to be emitted.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  CheckPacketIsFec(6, /*fec_group=*/5u);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Send more data with MAY_FEC_PROTECT. No FEC protection, so GetFecTimeout
  // returns infinite.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  consumed = generator_.ConsumeData(9, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  CheckPacketHasSingleStreamFrame(7);
  EXPECT_FALSE(creator_->IsFecProtected());
  EXPECT_EQ(QuicTime::Delta::Infinite(),
            generator_.GetFecTimeout(/*sequence_number=*/8u));
}

TEST_P(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
  // Set the packet size be enough for two stream frames with 0 stream offset,
  // but not enough for a stream frame of 0 offset and one with non-zero offset.
  size_t length =
      NullEncrypter().GetCiphertextSize(0) +
      GetPacketHeaderSize(
          creator_->connection_id_length(), true,
          QuicPacketCreatorPeer::NextSequenceNumberLength(creator_),
          NOT_IN_FEC_GROUP) +
      // Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger
      // than the GetMinStreamFrameSize.
      QuicFramer::GetMinStreamFrameSize(1, 0, false, NOT_IN_FEC_GROUP) + 3 +
      QuicFramer::GetMinStreamFrameSize(1, 0, true, NOT_IN_FEC_GROUP) + 1;
  generator_.SetMaxPacketLength(length, /*force=*/false);
  delegate_.SetCanWriteAnything();
  {
     InSequence dummy;
     EXPECT_CALL(delegate_, OnSerializedPacket(_))
         .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
     EXPECT_CALL(delegate_, OnSerializedPacket(_))
         .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  generator_.StartBatchOperations();
  // Queue enough data to prevent a stream frame with a non-zero offset from
  // fitting.
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 0, false,
                             MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(3u, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // This frame will not fit with the existing frame, causing the queued frame
  // to be serialized, and it will not fit with another frame like it, so it is
  // serialized by itself.
  consumed = generator_.ConsumeData(kHeadersStreamId, MakeIOVector("bar"), 3,
                                    true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(3u, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);
  CheckPacketContains(contents, 1);
}

TEST_P(QuicPacketGeneratorTest, NoFecPacketSentWhenBatchEnds) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(6);

  generator_.StartBatchOperations();

  generator_.ConsumeData(3, MakeIOVector("foo"), 2, true, MUST_FEC_PROTECT,
                         nullptr);
  QuicConsumedData consumed = generator_.ConsumeData(
      5, MakeIOVector("quux"), 7, false, MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(4u, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // Now both frames will be flushed out, but FEC packet is not yet sent.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.FinishBatchOperations();
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_stream_frames = 2u;
  contents.fec_group = 1u;
  CheckPacketContains(contents, 0);

  // Forcing FEC timeout causes FEC packet to be emitted.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  CheckPacketIsFec(1, /*fec_group=*/1u);
}

TEST_P(QuicPacketGeneratorTest, FecTimeoutOnRttChange) {
  EXPECT_EQ(QuicTime::Delta::Zero(),
            QuicPacketGeneratorPeer::GetFecTimeout(&generator_));
  generator_.OnRttChange(QuicTime::Delta::FromMilliseconds(300));
  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
            QuicPacketGeneratorPeer::GetFecTimeout(&generator_));
}

TEST_P(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(50);
  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
  EXPECT_FALSE(creator_->IsFecGroupOpen());

  // On reduced cwnd.
  generator_.OnCongestionWindowChange(7);
  EXPECT_EQ(3u, creator_->max_packets_per_fec_group());

  // On increased cwnd.
  generator_.OnCongestionWindowChange(100);
  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());

  // On collapsed cwnd.
  generator_.OnCongestionWindowChange(1);
  EXPECT_EQ(2u, creator_->max_packets_per_fec_group());
}

TEST_P(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();
  creator_->set_max_packets_per_fec_group(50);
  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
  EXPECT_FALSE(creator_->IsFecGroupOpen());

  // Send enough data to create 4 packets with MUST_FEC_PROTECT flag. 3 packets
  // are sent, one is queued in the creator.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  size_t data_len = 3 * kDefaultMaxPacketSize + 1;
  QuicConsumedData consumed = generator_.ConsumeData(
      7, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(creator_->IsFecGroupOpen());

  // Change FEC groupsize.
  generator_.OnCongestionWindowChange(2);
  EXPECT_EQ(2u, creator_->max_packets_per_fec_group());

  // If FEC send policy is FEC_ANY_TRIGGER, then send enough data to trigger one
  // unprotected data packet, causing the FEC packet to also be sent.
  //
  // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed and FEC packet
  // is not sent.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
  }
  consumed = generator_.ConsumeData(7, CreateData(kDefaultMaxPacketSize), 0,
                                    true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(kDefaultMaxPacketSize, consumed.bytes_consumed);
  if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
    // Verify that one FEC packet was sent.
    CheckPacketIsFec(4, /*fec_group=*/1u);
  }
  EXPECT_FALSE(creator_->IsFecGroupOpen());
  EXPECT_FALSE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnOff) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(2);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Send one unprotected data packet.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
                                                     MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
  EXPECT_FALSE(creator_->IsFecProtected());
  // Verify that one data packet was sent.
  PacketContents contents;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);

  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      // If FEC send policy is FEC_ALARM_TRIGGER, FEC group is closed.
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  // Send enough data to create 3 packets with MUST_FEC_PROTECT flag.
  size_t data_len = 2 * kDefaultMaxPacketSize + 100;
  consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // If FEC send policy is FEC_ANY_TRIGGER, verify that packets sent were 3 data
  // and 1 FEC.
  //
  // If FEC send policy is FEC_ALARM_TRIGGER, verify that packets sent were 3
  // data and FEC group is closed.
  CheckPacketHasSingleStreamFrame(1);
  CheckPacketHasSingleStreamFrame(2);
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    CheckPacketHasSingleStreamFrame(3);
  } else {
    CheckPacketIsFec(3, /*fec_group=*/2u);
    CheckPacketHasSingleStreamFrame(4);
  }

  // Calling OnFecTimeout should emit the pending FEC packet.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.OnFecTimeout();
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    CheckPacketIsFec(4, /*fec_group=*/4u);
  } else {
    CheckPacketIsFec(5, /*fec_group=*/5u);
  }

  // Send one unprotected data packet.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  consumed = generator_.ConsumeData(7, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
  EXPECT_FALSE(creator_->IsFecProtected());
  // Verify that one unprotected data packet was sent.
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    CheckPacketContains(contents, 5);
  } else {
    CheckPacketContains(contents, 6);
  }
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFrameInCreator) {
  delegate_.SetCanWriteAnything();
  // Enable FEC.
  creator_->set_max_packets_per_fec_group(2);

  generator_.StartBatchOperations();
  // Queue enough data to prevent a stream frame with a non-zero offset from
  // fitting.
  QuicConsumedData consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
                                                     MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  EXPECT_TRUE(creator_->HasPendingFrames());

  // Queue protected data for sending. Should cause queued frames to be flushed.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  EXPECT_FALSE(creator_->IsFecProtected());
  consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  PacketContents contents;
  contents.num_stream_frames = 1;
  // Transmitted packet was not FEC protected.
  CheckPacketContains(contents, 0);
  EXPECT_TRUE(creator_->IsFecProtected());
  EXPECT_TRUE(creator_->HasPendingFrames());
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) {
  // Enable FEC.
  creator_->set_max_packets_per_fec_group(2);

  // Queue control frames in generator.
  delegate_.SetCanNotWrite();
  generator_.SetShouldSendAck(true);
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  // Set up frames to write into the creator when control frames are written.
  EXPECT_CALL(delegate_, PopulateAckFrame(_));
  EXPECT_CALL(delegate_, PopulateStopWaitingFrame(_));

  // Generator should have queued control frames, and creator should be empty.
  EXPECT_TRUE(generator_.HasQueuedFrames());
  EXPECT_FALSE(creator_->HasPendingFrames());
  EXPECT_FALSE(creator_->IsFecProtected());

  // Queue protected data for sending. Should cause queued frames to be flushed.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
                                                     MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  PacketContents contents;
  contents.num_ack_frames = 1;
  contents.num_stop_waiting_frames = 1;
  CheckPacketContains(contents, 0);

  // FEC protection should be on in creator.
  EXPECT_TRUE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
  delegate_.SetCanWriteAnything();

  // Enable FEC.
  creator_->set_max_packets_per_fec_group(2);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Queue stream frame to be protected in creator.
  generator_.StartBatchOperations();
  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
                                                     MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  // Creator has a pending protected frame.
  EXPECT_TRUE(creator_->HasPendingFrames());
  EXPECT_TRUE(creator_->IsFecProtected());

  // Add enough unprotected data to exceed size of current packet, so that
  // current packet is sent. Both frames will be sent out in a single packet.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  size_t data_len = kDefaultMaxPacketSize;
  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
                                    MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  PacketContents contents;
  contents.num_stream_frames = 2u;
  contents.fec_group = 1u;
  CheckPacketContains(contents, 0);
  // FEC protection should still be on in creator.
  EXPECT_TRUE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
  delegate_.SetCanWriteAnything();

  // Enable FEC.
  creator_->set_max_packets_per_fec_group(2);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Send first packet, FEC protected.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
                                                     MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  PacketContents contents;
  contents.num_stream_frames = 1u;
  contents.fec_group = 1u;
  CheckPacketContains(contents, 0);

  // FEC should still be on in creator.
  EXPECT_TRUE(creator_->IsFecProtected());

  // Send unprotected data to cause second packet to be sent, which gets
  // protected because it happens to fall within an open FEC group. Data packet
  // will be followed by FEC packet.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
  }
  consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
                                    nullptr);
  EXPECT_EQ(1u, consumed.bytes_consumed);
  contents.num_stream_frames = 1u;
  CheckPacketContains(contents, 1);
  if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
    // FEC packet is sent when send policy is FEC_ANY_TRIGGER.
    CheckPacketIsFec(2, /*fec_group=*/1u);
  }

  // FEC protection should be off in creator.
  EXPECT_FALSE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  // Enable FEC.
  creator_->set_max_packets_per_fec_group(2);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Queue one byte of FEC protected data.
  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
                                                     MUST_FEC_PROTECT, nullptr);
  EXPECT_TRUE(creator_->HasPendingFrames());

  // Add more unprotected data causing first packet to be sent, FEC protected.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  size_t data_len = kDefaultMaxPacketSize;
  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
                                    MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  PacketContents contents;
  contents.num_stream_frames = 2u;
  contents.fec_group = 1u;
  CheckPacketContains(contents, 0);

  // FEC group is still open in creator.
  EXPECT_TRUE(creator_->IsFecProtected());

  // Add data that should be protected, large enough to cause second packet to
  // be sent. Data packet should be followed by FEC packet.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
  }
  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  CheckPacketContains(contents, 1);
  if (generator_.fec_send_policy() == FEC_ANY_TRIGGER) {
    // FEC packet is sent when send policy is FEC_ANY_TRIGGER.
    CheckPacketIsFec(2, /*fec_group=*/1u);
  }

  // FEC protection should remain on in creator.
  EXPECT_TRUE(creator_->IsFecProtected());
}

TEST_P(QuicPacketGeneratorTest, ResetFecGroupNoTimeout) {
  delegate_.SetCanWriteAnything();
  // Send FEC packet after 2 packets.
  creator_->set_max_packets_per_fec_group(2);
  EXPECT_FALSE(creator_->IsFecProtected());

  // Send two packets so that when this data is consumed, two packets are sent
  // out. In FEC_TRIGGER_ANY, this will cause an FEC packet to be sent out and
  // with FEC_TRIGGER_ALARM, this will cause a Reset to be called. In both
  // cases, the creator's fec protection will be turned off afterwards.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER, but FEC
      // group is closed.
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
    // Fin Packet.
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }
  size_t data_len = 2 * kDefaultMaxPacketSize;
  QuicConsumedData consumed = generator_.ConsumeData(
      5, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
  CheckPacketHasSingleStreamFrame(0);
  CheckPacketHasSingleStreamFrame(1);
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    // FEC packet is not sent when send policy is FEC_ALARM_TRIGGER.
    CheckPacketHasSingleStreamFrame(2);
  } else {
    // FEC packet is sent after 2 packets and when send policy is
    // FEC_ANY_TRIGGER.
    CheckPacketIsFec(2, 1);
    CheckPacketHasSingleStreamFrame(3);
  }
  EXPECT_TRUE(creator_->IsFecProtected());

  // Do the same send  (with MUST_FEC_PROTECT) on a different stream id.
  {
    InSequence dummy;
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    // FEC packet is sent after 2 packets and when send policy is
    // FEC_ANY_TRIGGER. When policy is FEC_ALARM_TRIGGER, FEC group is closed
    // and FEC packet is not sent.
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    // FEC packet is sent after 2 packets and when send policy is
    // FEC_ANY_TRIGGER. When policy is FEC_ALARM_TRIGGER, FEC group is closed
    // and FEC packet is not sent.
    if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
      EXPECT_CALL(delegate_, OnResetFecGroup()).Times(1);
    } else {
      EXPECT_CALL(delegate_, OnSerializedPacket(_))
          .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    }
  }
  consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
                                    MUST_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());
  if (generator_.fec_send_policy() == FEC_ALARM_TRIGGER) {
    CheckPacketHasSingleStreamFrame(3);
    CheckPacketHasSingleStreamFrame(4);
    CheckPacketHasSingleStreamFrame(5);
  } else {
    CheckPacketHasSingleStreamFrame(4);
    // FEC packet is sent after 2 packets and when send policy is
    // FEC_ANY_TRIGGER.
    CheckPacketIsFec(5, 4);
    CheckPacketHasSingleStreamFrame(6);
    CheckPacketHasSingleStreamFrame(7);
    // FEC packet is sent after 2 packets and when send policy is
    // FEC_ANY_TRIGGER.
    CheckPacketIsFec(8, 7);
  }
  EXPECT_TRUE(creator_->IsFecProtected());
}

// 1. Create and send one packet with MUST_FEC_PROTECT.
// 2. Call FecTimeout, expect FEC packet is sent.
// 3. Do the same thing over again, with a different stream id.
TEST_P(QuicPacketGeneratorTest, FecPacketSentOnFecTimeout) {
  delegate_.SetCanWriteAnything();
  creator_->set_max_packets_per_fec_group(1000);
  EXPECT_FALSE(creator_->IsFecProtected());

  for (int i = 1; i < 4; i = i + 2) {
    // Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the
    // creator FEC protects all data.
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    QuicConsumedData consumed = generator_.ConsumeData(
        i + 2, CreateData(1u), 0, true, MUST_FEC_PROTECT, nullptr);
    EXPECT_EQ(1u, consumed.bytes_consumed);
    EXPECT_TRUE(consumed.fin_consumed);
    CheckPacketHasSingleStreamFrame(0);
    EXPECT_TRUE(creator_->IsFecProtected());

    // Calling OnFecTimeout should cause the FEC packet to be emitted.
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    generator_.OnFecTimeout();
    CheckPacketIsFec(i, i);
    EXPECT_FALSE(creator_->IsFecProtected());
  }
}

TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
  delegate_.SetCanNotWrite();

  generator_.SetShouldSendAck(false);
  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());

  delegate_.SetCanWriteAnything();

  generator_.StartBatchOperations();

  // When the first write operation is invoked, the ack frame will be returned.
  EXPECT_CALL(delegate_, PopulateAckFrame(_));

  // Send some data and a control frame
  generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT,
                         nullptr);
  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));

  // All five frames will be flushed out in a single packet.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  generator_.FinishBatchOperations();
  EXPECT_FALSE(generator_.HasQueuedFrames());

  PacketContents contents;
  contents.num_ack_frames = 1;
  contents.num_goaway_frames = 1;
  contents.num_rst_stream_frames = 1;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);
}

TEST_P(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
  delegate_.SetCanNotWrite();

  generator_.SetShouldSendAck(false);
  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
  EXPECT_TRUE(generator_.HasQueuedFrames());

  delegate_.SetCanWriteAnything();

  generator_.StartBatchOperations();

  // When the first write operation is invoked, the ack frame will be returned.
  EXPECT_CALL(delegate_, PopulateAckFrame(_));

  {
    InSequence dummy;
    // All five frames will be flushed out in a single packet
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
    EXPECT_CALL(delegate_, OnSerializedPacket(_))
        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  }

  // Send enough data to exceed one packet
  size_t data_len = kDefaultMaxPacketSize + 100;
  QuicConsumedData consumed = generator_.ConsumeData(
      3, CreateData(data_len), 0, true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));

  generator_.FinishBatchOperations();
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // The first packet should have the queued data and part of the stream data.
  PacketContents contents;
  contents.num_ack_frames = 1;
  contents.num_rst_stream_frames = 1;
  contents.num_stream_frames = 1;
  CheckPacketContains(contents, 0);

  // The second should have the remainder of the stream data.
  PacketContents contents2;
  contents2.num_goaway_frames = 1;
  contents2.num_stream_frames = 1;
  CheckPacketContains(contents2, 1);
}

TEST_P(QuicPacketGeneratorTest, TestConnectionIdLength) {
  generator_.SetConnectionIdLength(0);
  EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(1);
  EXPECT_EQ(PACKET_1BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(2);
  EXPECT_EQ(PACKET_4BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(3);
  EXPECT_EQ(PACKET_4BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(4);
  EXPECT_EQ(PACKET_4BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(5);
  EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(6);
  EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(7);
  EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(8);
  EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
  generator_.SetConnectionIdLength(9);
  EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
}

// Test whether SetMaxPacketLength() works in the situation when the queue is
// empty, and we send three packets worth of data.
TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) {
  delegate_.SetCanWriteAnything();

  // Send enough data for three packets.
  size_t data_len = 3 * kDefaultMaxPacketSize + 1;
  size_t packet_len = kDefaultMaxPacketSize + 100;
  ASSERT_LE(packet_len, kMaxPacketSize);
  generator_.SetMaxPacketLength(packet_len, /*force=*/false);
  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .Times(3)
      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
                             /*offset=*/2,
                             /*fin=*/true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // We expect three packets, and first two of them have to be of packet_len
  // size.  We check multiple packets (instead of just one) because we want to
  // ensure that |max_packet_length_| does not get changed incorrectly by the
  // generator after first packet is serialized.
  ASSERT_EQ(3u, packets_.size());
  EXPECT_EQ(packet_len, packets_[0].packet->length());
  EXPECT_EQ(packet_len, packets_[1].packet->length());
  CheckAllPacketsHaveSingleStreamFrame();
}

// Test whether SetMaxPacketLength() works in the situation when we first write
// data, then change packet size, then write data again.
TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) {
  delegate_.SetCanWriteAnything();

  // We send enough data to overflow default packet length, but not the altered
  // one.
  size_t data_len = kDefaultMaxPacketSize;
  size_t packet_len = kDefaultMaxPacketSize + 100;
  ASSERT_LE(packet_len, kMaxPacketSize);

  // We expect to see three packets in total.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .Times(3)
      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  // Send two packets before packet size change.
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
                             /*offset=*/2,
                             /*fin=*/false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // Make sure we already have two packets.
  ASSERT_EQ(2u, packets_.size());

  // Increase packet size.
  generator_.SetMaxPacketLength(packet_len, /*force=*/false);
  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());

  // Send a packet after packet size change.
  consumed = generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
                                    2 + data_len,
                                    /*fin=*/true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // We expect first data chunk to get fragmented, but the second one to fit
  // into a single packet.
  ASSERT_EQ(3u, packets_.size());
  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].packet->length());
  EXPECT_LE(kDefaultMaxPacketSize, packets_[2].packet->length());
  CheckAllPacketsHaveSingleStreamFrame();
}

// Test whether SetMaxPacketLength() works correctly when we change the packet
// size in the middle of the batched packet.
TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_Midpacket) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  size_t first_write_len = kDefaultMaxPacketSize / 2;
  size_t second_write_len = kDefaultMaxPacketSize;
  size_t packet_len = kDefaultMaxPacketSize + 100;
  ASSERT_LE(packet_len, kMaxPacketSize);

  // First send half of the packet worth of data.  We are in the batch mode, so
  // should not cause packet serialization.
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(first_write_len),
                             /*offset=*/2,
                             /*fin=*/false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(first_write_len, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // Make sure we have no packets so far.
  ASSERT_EQ(0u, packets_.size());

  // Increase packet size.  Ensure it's not immediately enacted.
  generator_.SetMaxPacketLength(packet_len, /*force=*/false);
  EXPECT_EQ(packet_len, generator_.GetMaxPacketLength());
  EXPECT_EQ(kDefaultMaxPacketSize, generator_.GetCurrentMaxPacketLength());

  // We expect to see exactly one packet serialized after that, since we are in
  // batch mode and we have sent approximately 3/2 of our MTU.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  // Send a packet worth of data to the same stream.  This should trigger
  // serialization of other packet.
  consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(second_write_len),
                             /*offset=*/2 + first_write_len,
                             /*fin=*/true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(second_write_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // We expect the first packet to contain two frames, and to not reflect the
  // packet size change.
  ASSERT_EQ(1u, packets_.size());
  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].packet->length());

  PacketContents contents;
  contents.num_stream_frames = 2;
  CheckPacketContains(contents, 0);
}

// Test whether SetMaxPacketLength() works correctly when we force the change of
// the packet size in the middle of the batched packet.
TEST_P(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) {
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  size_t first_write_len = kDefaultMaxPacketSize / 2;
  size_t packet_len = kDefaultMaxPacketSize + 100;
  size_t second_write_len = packet_len + 1;
  ASSERT_LE(packet_len, kMaxPacketSize);

  // First send half of the packet worth of data.  We are in the batch mode, so
  // should not cause packet serialization.
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(first_write_len),
                             /*offset=*/2,
                             /*fin=*/false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(first_write_len, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // Make sure we have no packets so far.
  ASSERT_EQ(0u, packets_.size());

  // Expect a packet to be flushed.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  // Increase packet size.  Ensure it's immediately enacted.
  generator_.SetMaxPacketLength(packet_len, /*force=*/true);
  EXPECT_EQ(packet_len, generator_.GetMaxPacketLength());
  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // We expect to see exactly one packet serialized after that, because we send
  // a value somewhat exceeding new max packet size, and the tail data does not
  // get serialized because we are still in the batch mode.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  // Send a more than a packet worth of data to the same stream.  This should
  // trigger serialization of one packet, and queue another one.
  consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(second_write_len),
                             /*offset=*/2 + first_write_len,
                             /*fin=*/true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(second_write_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_TRUE(generator_.HasQueuedFrames());

  // We expect the first packet to be underfilled, and the second packet be up
  // to the new max packet size.
  ASSERT_EQ(2u, packets_.size());
  EXPECT_GT(kDefaultMaxPacketSize, packets_[0].packet->length());
  EXPECT_EQ(packet_len, packets_[1].packet->length());

  CheckAllPacketsHaveSingleStreamFrame();
}

// Test sending an MTU probe, without any surrounding data.
TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_Simple) {
  delegate_.SetCanWriteAnything();

  const size_t target_mtu = kDefaultMaxPacketSize + 100;
  static_assert(target_mtu < kMaxPacketSize,
                "The MTU probe used by the test exceeds maximum packet size");

  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  generator_.GenerateMtuDiscoveryPacket(target_mtu, nullptr);

  EXPECT_FALSE(generator_.HasQueuedFrames());
  ASSERT_EQ(1u, packets_.size());
  EXPECT_EQ(target_mtu, packets_[0].packet->length());

  PacketContents contents;
  contents.num_mtu_discovery_frames = 1;
  CheckPacketContains(contents, 0);
}

// Test sending an MTU probe.  Surround it with data, to ensure that it resets
// the MTU to the value before the probe was sent.
TEST_P(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) {
  delegate_.SetCanWriteAnything();

  const size_t target_mtu = kDefaultMaxPacketSize + 100;
  static_assert(target_mtu < kMaxPacketSize,
                "The MTU probe used by the test exceeds maximum packet size");

  // Send enough data so it would always cause two packets to be sent.
  const size_t data_len = target_mtu + 1;

  // Send a total of five packets: two packets before the probe, the probe
  // itself, and two packets after the probe.
  EXPECT_CALL(delegate_, OnSerializedPacket(_))
      .Times(5)
      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));

  // Send data before the MTU probe.
  QuicConsumedData consumed =
      generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
                             /*offset=*/2,
                             /*fin=*/false, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_FALSE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // Send the MTU probe.
  generator_.GenerateMtuDiscoveryPacket(target_mtu, nullptr);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  // Send data after the MTU probe.
  consumed = generator_.ConsumeData(kHeadersStreamId, CreateData(data_len),
                                    /*offset=*/2 + data_len,
                                    /*fin=*/true, MAY_FEC_PROTECT, nullptr);
  EXPECT_EQ(data_len, consumed.bytes_consumed);
  EXPECT_TRUE(consumed.fin_consumed);
  EXPECT_FALSE(generator_.HasQueuedFrames());

  ASSERT_EQ(5u, packets_.size());
  EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].packet->length());
  EXPECT_EQ(target_mtu, packets_[2].packet->length());
  EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].packet->length());

  PacketContents probe_contents;
  probe_contents.num_mtu_discovery_frames = 1;

  CheckPacketHasSingleStreamFrame(0);
  CheckPacketHasSingleStreamFrame(1);
  CheckPacketContains(probe_contents, 2);
  CheckPacketHasSingleStreamFrame(3);
  CheckPacketHasSingleStreamFrame(4);
}

TEST_P(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
  // Test added to ensure the generator does not crash when an invalid frame is
  // added.  Because this is an indication of internal programming errors,
  // DFATALs are expected.
  // A 1 byte sequence number length can't encode a gap of 1000.
  QuicPacketCreatorPeer::SetSequenceNumber(creator_, 1000);

  delegate_.SetCanNotWrite();
  generator_.SetShouldSendAck(true);
  delegate_.SetCanWriteAnything();
  generator_.StartBatchOperations();

  // Set up frames to write into the creator when control frames are written.
  EXPECT_CALL(delegate_, PopulateAckFrame(_));
  EXPECT_CALL(delegate_, PopulateStopWaitingFrame(_));
  // Generator should have queued control frames, and creator should be empty.
  EXPECT_TRUE(generator_.HasQueuedFrames());
  EXPECT_FALSE(creator_->HasPendingFrames());

  // This will not serialize any packets, because of the invalid frame.
  EXPECT_CALL(delegate_,
              CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false));
  EXPECT_DFATAL(generator_.FinishBatchOperations(),
                "sequence_number_length 1 is too small "
                "for least_unacked_delta: 1001");
}

}  // namespace test
}  // namespace net
