// Copyright (c) 2018 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.

// gunit tests for the IETF-format framer --- generally does a simple test
// for each framer; we generate the template object (eg
// QuicIetfStreamFrame) with the correct stuff in it, ask that a frame
// be serialized (call AppendIetf<mumble>) then deserialized (call
// ProcessIetf<mumble>) and then check that the gazintas and gazoutas
// are the same.
//
// We do minimal checking of the serialized frame
//
// We do look at various different values (resulting in different
// length varints, etc)

#include "net/third_party/quiche/src/quic/core/quic_framer.h"

#include <algorithm>
#include <cstdint>
#include <map>
#include <memory>
#include <vector>

#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"

namespace quic {
namespace test {
namespace {

const size_t kNormalPacketBufferSize = 1400;
// Several different stream ids, should be encoded
// in 8, 4, 2, and 1 byte, respectively. Last one
// checks that value==0 works.
// All stream IDs end in 0x0, so the client/server- initiated
// and Uni/Bi-directional bits are available to alter, as any
// given test may wish.
const QuicIetfStreamId kStreamId8 = UINT64_C(0x3EDCBA9876543210);
const QuicIetfStreamId kStreamId4 = UINT64_C(0x36543210);
const QuicIetfStreamId kStreamId2 = UINT64_C(0x3210);
const QuicIetfStreamId kStreamId1 = UINT64_C(0x10);
const QuicIetfStreamId kStreamId0 = UINT64_C(0x00);

// Ditto for the offsets.
const QuicIetfStreamOffset kOffset8 = UINT64_C(0x3210BA9876543210);
const QuicIetfStreamOffset kOffset4 = UINT64_C(0x32109876);
const QuicIetfStreamOffset kOffset2 = UINT64_C(0x3456);
const QuicIetfStreamOffset kOffset1 = UINT64_C(0x3f);
const QuicIetfStreamOffset kOffset0 = UINT64_C(0x00);

// Structures used to create various ack frames.

// Defines an ack frame to feed through the framer/deframer.
struct ack_frame {
  uint64_t delay_time;
  bool is_ack_ecn;
  QuicPacketCount ect_0_count;
  QuicPacketCount ect_1_count;
  QuicPacketCount ecn_ce_count;
  const std::vector<QuicAckBlock>& ranges;
  uint64_t expected_frame_type;
};

class TestQuicVisitor : public QuicFramerVisitorInterface {
 public:
  TestQuicVisitor() {}

  ~TestQuicVisitor() override {}

  void OnError(QuicFramer* f) override {
    QUIC_DLOG(INFO) << "QuicIetfFramer Error: "
                    << QuicErrorCodeToString(f->error()) << " (" << f->error()
                    << ")";
  }

  void OnPacket() override {}

  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}

  void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& packet) override {}

  bool OnProtocolVersionMismatch(ParsedQuicVersion received_version,
                                 PacketHeaderFormat form) override {
    return true;
  }

  bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
    return true;
  }

  bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
    return true;
  }

  void OnDecryptedPacket(EncryptionLevel level) override {}

  bool OnPacketHeader(const QuicPacketHeader& header) override { return true; }

  void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {}

  bool OnStreamFrame(const QuicStreamFrame& frame) override { return true; }

  bool OnCryptoFrame(const QuicCryptoFrame& frame) override { return true; }

  bool OnAckFrameStart(QuicPacketNumber largest_acked,
                       QuicTime::Delta ack_delay_time) override {
    return true;
  }

  bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
    return true;
  }

  bool OnAckTimestamp(QuicPacketNumber packet_number,
                      QuicTime timestamp) override {
    return true;
  }

  bool OnAckFrameEnd(QuicPacketNumber start) override { return true; }

  bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
    return true;
  }

  bool OnPaddingFrame(const QuicPaddingFrame& frame) override { return true; }

  bool OnPingFrame(const QuicPingFrame& frame) override { return true; }

  bool OnMessageFrame(const QuicMessageFrame& frame) override { return true; }

  void OnPacketComplete() override {}

  bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
    return true;
  }

  bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
    return true;
  }

  bool OnApplicationCloseFrame(
      const QuicApplicationCloseFrame& frame) override {
    return true;
  }

  bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
    return true;
  }

  bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
    return true;
  }
  bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
    return true;
  }

  bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override { return true; }

  bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
    return true;
  }

  bool OnBlockedFrame(const QuicBlockedFrame& frame) override { return true; }

  bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
    return true;
  }

  bool OnRetireConnectionIdFrame(
      const QuicRetireConnectionIdFrame& frame) override {
    return true;
  }

  bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override { return true; }

  bool IsValidStatelessResetToken(QuicUint128 token) const override {
    return true;
  }

  void OnAuthenticatedIetfStatelessResetPacket(
      const QuicIetfStatelessResetPacket& packet) override {}

  bool OnMaxStreamIdFrame(const QuicMaxStreamIdFrame& frame) override {
    return true;
  }

  bool OnStreamIdBlockedFrame(const QuicStreamIdBlockedFrame& frame) override {
    return true;
  }
};

class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
 public:
  QuicIetfFramerTest()
      : start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
        framer_(AllSupportedVersions(),
                start_,
                Perspective::IS_SERVER,
                kQuicDefaultConnectionIdLength) {
    framer_.set_visitor(&visitor_);
  }

  // Utility functions to do actual framing/deframing.
  void TryStreamFrame(char* packet_buffer,
                      size_t packet_buffer_size,
                      const char* xmit_packet_data,
                      size_t xmit_packet_data_size,
                      QuicIetfStreamId stream_id,
                      QuicIetfStreamOffset offset,
                      bool fin_bit,
                      bool last_frame_bit,
                      QuicIetfFrameType frame_type) {
    // initialize a writer so that the serialized packet is placed in
    // packet_buffer.
    QuicDataWriter writer(packet_buffer_size, packet_buffer,
                          NETWORK_BYTE_ORDER);  // do not really care
                                                // about endianness.
    // set up to define the source frame we wish to send.
    QuicStreamFrame source_stream_frame(
        stream_id, fin_bit, offset, xmit_packet_data, xmit_packet_data_size);

    // Write the frame to the packet buffer.
    EXPECT_TRUE(QuicFramerPeer::AppendIetfStreamFrame(
        &framer_, source_stream_frame, last_frame_bit, &writer));
    // Better have something in the packet buffer.
    EXPECT_NE(0u, writer.length());
    // Now set up a reader to read in the frame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

    // A StreamFrame to hold the results... we know the frame type,
    // put it into the QuicIetfStreamFrame
    QuicStreamFrame sink_stream_frame;
    if (xmit_packet_data_size) {
      EXPECT_EQ(sink_stream_frame.data_buffer, nullptr);
      EXPECT_EQ(sink_stream_frame.data_length, 0u);
    }

    EXPECT_TRUE(QuicFramerPeer::ProcessIetfStreamFrame(
        &framer_, &reader, frame_type, &sink_stream_frame));

    // Now check that the streamid, fin-bit, offset, and
    // data len all match the input.
    EXPECT_EQ(sink_stream_frame.stream_id, source_stream_frame.stream_id);
    EXPECT_EQ(sink_stream_frame.fin, source_stream_frame.fin);
    EXPECT_EQ(sink_stream_frame.data_length, source_stream_frame.data_length);
    if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
      // There was an offset in the frame, see if xmit and rcv vales equal.
      EXPECT_EQ(sink_stream_frame.offset, source_stream_frame.offset);
    } else {
      // Offset not in frame, so it better come out 0.
      EXPECT_EQ(sink_stream_frame.offset, 0u);
    }
    if (xmit_packet_data_size) {
      ASSERT_NE(sink_stream_frame.data_buffer, nullptr);
      ASSERT_NE(source_stream_frame.data_buffer, nullptr);
      EXPECT_EQ(strcmp(sink_stream_frame.data_buffer,
                       source_stream_frame.data_buffer),
                0);
    } else {
      // No data in the frame.
      EXPECT_EQ(source_stream_frame.data_length, 0u);
      EXPECT_EQ(sink_stream_frame.data_length, 0u);
    }
  }

  // Overall ack frame encode/decode/compare function
  //  Encodes an ack frame as specified at |*frame|
  //  Then decodes the frame,
  //  Then compares the two
  // Does some basic checking:
  //   - did the writer write something?
  //   - did the reader read the entire packet?
  //   - did the things the reader read match what the writer wrote?
  // Returns true if it all worked false if not.
  bool TryAckFrame(char* packet_buffer,
                   size_t packet_buffer_size,
                   struct ack_frame* frame) {
    QuicAckFrame transmit_frame = InitAckFrame(frame->ranges);
    if (frame->is_ack_ecn) {
      transmit_frame.ecn_counters_populated = true;
      transmit_frame.ect_0_count = frame->ect_0_count;
      transmit_frame.ect_1_count = frame->ect_1_count;
      transmit_frame.ecn_ce_count = frame->ecn_ce_count;
    }
    transmit_frame.ack_delay_time =
        QuicTime::Delta::FromMicroseconds(frame->delay_time);
    size_t expected_size =
        QuicFramerPeer::GetIetfAckFrameSize(&framer_, transmit_frame);

    // Make a writer so that the serialized packet is placed in
    // packet_buffer.
    QuicDataWriter writer(expected_size, packet_buffer, NETWORK_BYTE_ORDER);

    // Write the frame to the packet buffer.
    EXPECT_TRUE(QuicFramerPeer::AppendIetfAckFrameAndTypeByte(
        &framer_, transmit_frame, &writer));

    size_t expected_frame_length = QuicFramerPeer::ComputeFrameLength(
        &framer_, QuicFrame(&transmit_frame), false,
        static_cast<QuicPacketNumberLength>(123456u));

    // Encoded length should match what ComputeFrameLength returns
    EXPECT_EQ(expected_frame_length, writer.length());
    // and what is in the buffer should be the expected size.
    EXPECT_EQ(expected_size, writer.length()) << "Frame is " << transmit_frame;
    // Now set up a reader to read in the frame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

    // read in the frame type
    uint8_t received_frame_type;
    EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
    EXPECT_EQ(frame->expected_frame_type, received_frame_type);

    // an AckFrame to hold the results
    QuicAckFrame receive_frame;

    EXPECT_TRUE(QuicFramerPeer::ProcessIetfAckFrame(
        &framer_, &reader, received_frame_type, &receive_frame));

    if (frame->is_ack_ecn &&
        (frame->ect_0_count || frame->ect_1_count || frame->ecn_ce_count)) {
      EXPECT_TRUE(receive_frame.ecn_counters_populated);
      EXPECT_EQ(receive_frame.ect_0_count, frame->ect_0_count);
      EXPECT_EQ(receive_frame.ect_1_count, frame->ect_1_count);
      EXPECT_EQ(receive_frame.ecn_ce_count, frame->ecn_ce_count);
    } else {
      EXPECT_FALSE(receive_frame.ecn_counters_populated);
      EXPECT_EQ(receive_frame.ect_0_count, 0u);
      EXPECT_EQ(receive_frame.ect_1_count, 0u);
      EXPECT_EQ(receive_frame.ecn_ce_count, 0u);
    }

    // Now check that the received frame matches the sent frame.
    EXPECT_EQ(transmit_frame.largest_acked, receive_frame.largest_acked);
    // The ~0x7 needs some explaining.  The ack frame format down shifts the
    // delay time by 3 (divide by 8) to allow for greater ranges in delay time.
    // Therefore, if we give the framer a delay time that is not an
    // even multiple of 8, the value that the deframer produces will
    // not be the same as what the framer got. The downshift on
    // framing and upshift on deframing results in clearing the 3
    // low-order bits ... The masking basically does the same thing,
    // so the compare works properly.
    return true;
  }

  // encode, decode, and check a Path Challenge frame.
  bool TryPathChallengeFrame(char* packet_buffer,
                             size_t packet_buffer_size,
                             const QuicPathFrameBuffer& data) {
    // Make a writer so that the serialized packet is placed in
    // packet_buffer.
    QuicDataWriter writer(packet_buffer_size, packet_buffer,
                          NETWORK_BYTE_ORDER);

    QuicPathChallengeFrame transmit_frame(0, data);

    // write the frame to the packet buffer.
    EXPECT_TRUE(QuicFramerPeer::AppendPathChallengeFrame(
        &framer_, transmit_frame, &writer));

    // Check for correct length in the packet buffer.
    EXPECT_EQ(kQuicPathChallengeFrameSize, writer.length());

    // now set up a reader to read in the frame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

    QuicPathChallengeFrame receive_frame;

    EXPECT_TRUE(QuicFramerPeer::ProcessPathChallengeFrame(&framer_, &reader,
                                                          &receive_frame));

    // Now check that the received frame matches the sent frame.
    EXPECT_EQ(
        0, memcmp(transmit_frame.data_buffer.data(),
                  receive_frame.data_buffer.data(), kQuicPathFrameBufferSize));
    return true;
  }

  // encode, decode, and check a Path Response frame.
  bool TryPathResponseFrame(char* packet_buffer,
                            size_t packet_buffer_size,
                            const QuicPathFrameBuffer& data) {
    // Make a writer so that the serialized packet is placed in
    // packet_buffer.
    QuicDataWriter writer(packet_buffer_size, packet_buffer,
                          NETWORK_BYTE_ORDER);

    QuicPathResponseFrame transmit_frame(0, data);

    // Write the frame to the packet buffer.
    EXPECT_TRUE(QuicFramerPeer::AppendPathResponseFrame(
        &framer_, transmit_frame, &writer));

    // Check for correct length in the packet buffer.
    EXPECT_EQ(kQuicPathResponseFrameSize, writer.length());

    // Set up a reader to read in the frame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

    QuicPathResponseFrame receive_frame;

    EXPECT_TRUE(QuicFramerPeer::ProcessPathResponseFrame(&framer_, &reader,
                                                         &receive_frame));

    // Now check that the received frame matches the sent frame.
    EXPECT_EQ(
        0, memcmp(transmit_frame.data_buffer.data(),
                  receive_frame.data_buffer.data(), kQuicPathFrameBufferSize));
    return true;
  }

  // Test the Serialization/deserialization of a Reset Stream Frame.
  void TryResetFrame(char* packet_buffer,
                     size_t packet_buffer_size,
                     QuicStreamId stream_id,
                     uint16_t error_code,
                     QuicStreamOffset final_offset) {
    // Initialize a writer so that the serialized packet is placed in
    // packet_buffer.
    QuicDataWriter writer(packet_buffer_size, packet_buffer,
                          NETWORK_BYTE_ORDER);

    QuicRstStreamFrame transmit_frame(static_cast<QuicControlFrameId>(1),
                                      stream_id, error_code, final_offset);

    // Write the frame to the packet buffer.
    EXPECT_TRUE(QuicFramerPeer::AppendIetfResetStreamFrame(
        &framer_, transmit_frame, &writer));
    // Check that the size of the serialzed frame is in the allowed range.
    EXPECT_LT(3u, writer.length());
    EXPECT_GT(19u, writer.length());
    // Now set up a reader to read in the thing in.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

    // A QuicRstStreamFrame to hold the results
    QuicRstStreamFrame receive_frame;
    EXPECT_TRUE(QuicFramerPeer::ProcessIetfResetStreamFrame(&framer_, &reader,
                                                            &receive_frame));

    // Now check that the received values match the input.
    EXPECT_EQ(receive_frame.stream_id, transmit_frame.stream_id);
    EXPECT_EQ(receive_frame.ietf_error_code, transmit_frame.ietf_error_code);
    EXPECT_EQ(receive_frame.byte_offset, transmit_frame.byte_offset);
  }

  void TryMaxStreamsFrame(QuicStreamId stream_id,
                          bool unidirectional,
                          bool stream_id_server_initiated) {
    if (!unidirectional && !stream_id_server_initiated && stream_id == 0) {
      // For bidirectional, client initiated, streams, 0 is not allowed,
      // it's used for the crypto stream and is not included in the counting.
      return;
    }

    char packet_buffer[kNormalPacketBufferSize];
    memset(packet_buffer, 0, sizeof(packet_buffer));

    Perspective old_perspective = framer_.perspective();
    // Set up the writer and transmit QuicMaxStreamIdFrame
    QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                          NETWORK_BYTE_ORDER);
    if (stream_id_server_initiated) {
      stream_id |= 0x01;
    }
    if (unidirectional) {
      stream_id |= 0x02;
    }

    // Set the perspective of the sender. If the stream id is supposed to
    // be server-initiated, then the sender of the MAX_STREAMS should be
    // a client, and vice versa. Do this prior to constructing the frame or
    // generating the packet, so that any internal dependencies are satisfied.
    QuicFramerPeer::SetPerspective(&framer_, (stream_id_server_initiated)
                                                 ? Perspective::IS_CLIENT
                                                 : Perspective::IS_SERVER);
    QuicMaxStreamIdFrame transmit_frame(0, stream_id);

    // Add the frame.
    EXPECT_TRUE(QuicFramerPeer::AppendMaxStreamsFrame(&framer_, transmit_frame,
                                                      &writer));

    // Check that buffer length is in the expected range
    EXPECT_LE(1u, writer.length());
    EXPECT_GE(8u, writer.length());

    // Set the perspective for the receiver.
    QuicFramerPeer::SetPerspective(&framer_, (stream_id_server_initiated)
                                                 ? Perspective::IS_SERVER
                                                 : Perspective::IS_CLIENT);

    // Set up reader and empty receive QuicPaddingFrame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
    QuicMaxStreamIdFrame receive_frame;

    // Deframe it
    EXPECT_TRUE(QuicFramerPeer::ProcessMaxStreamsFrame(
        &framer_, &reader, &receive_frame,
        (unidirectional) ? IETF_MAX_STREAMS_UNIDIRECTIONAL
                         : IETF_MAX_STREAMS_BIDIRECTIONAL))
        << " Error: " << framer_.detailed_error();

    // Now check that received and sent data are equivalent
    EXPECT_EQ(stream_id, receive_frame.max_stream_id);
    EXPECT_EQ(transmit_frame.max_stream_id, receive_frame.max_stream_id);
    QuicFramerPeer::SetPerspective(&framer_, old_perspective);
  }

  void TryStreamsBlockedFrame(QuicStreamId stream_id,
                              bool unidirectional,
                              bool stream_id_server_initiated) {
    if (!unidirectional && !stream_id_server_initiated && stream_id == 0) {
      // For bidirectional, client initiated, streams, 0 is not allowed,
      // it's used for the crypto stream and is not included in the counting.
      return;
    }

    char packet_buffer[kNormalPacketBufferSize];
    memset(packet_buffer, 0, sizeof(packet_buffer));

    Perspective old_perspective = framer_.perspective();
    // Set up the writer and transmit QuicMaxStreamIdFrame
    QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                          NETWORK_BYTE_ORDER);
    if (stream_id_server_initiated) {
      stream_id |= 0x01;
    }
    if (unidirectional) {
      stream_id |= 0x02;
    }

    // Set the perspective of the sender. If the stream id is supposed to
    // be server-initiated, then the sender of the MAX_STREAMS should be
    // a client, and vice versa. Do this prior to constructing the frame or
    // generating the packet, so that any internal dependencies are satisfied.
    QuicFramerPeer::SetPerspective(&framer_, (stream_id_server_initiated)
                                                 ? Perspective::IS_SERVER
                                                 : Perspective::IS_CLIENT);
    QuicStreamIdBlockedFrame transmit_frame(0, stream_id);

    // Add the frame.
    EXPECT_TRUE(QuicFramerPeer::AppendStreamsBlockedFrame(
        &framer_, transmit_frame, &writer));

    // Check that buffer length is in the expected range
    EXPECT_LE(1u, writer.length());
    EXPECT_GE(8u, writer.length());

    // Set the perspective for the receiver.
    QuicFramerPeer::SetPerspective(&framer_, (stream_id_server_initiated)
                                                 ? Perspective::IS_CLIENT
                                                 : Perspective::IS_SERVER);

    // Set up reader and empty receive QuicPaddingFrame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
    QuicStreamIdBlockedFrame receive_frame;

    // Deframe it
    EXPECT_TRUE(QuicFramerPeer::ProcessStreamsBlockedFrame(
        &framer_, &reader, &receive_frame,
        (unidirectional) ? IETF_STREAMS_BLOCKED_UNIDIRECTIONAL
                         : IETF_STREAMS_BLOCKED_BIDIRECTIONAL));

    // Now check that received and sent data are equivalent
    EXPECT_EQ(stream_id, receive_frame.stream_id);
    EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
    QuicFramerPeer::SetPerspective(&framer_, old_perspective);
  }

  QuicTime start_;
  QuicFramer framer_;
  test::TestQuicVisitor visitor_;
};

struct stream_frame_variant {
  QuicIetfStreamId stream_id;
  QuicIetfStreamOffset offset;
  bool fin_bit;
  bool last_frame_bit;
  uint8_t frame_type;
} stream_frame_to_test[] = {
#define IETF_STREAM0 (((uint8_t)IETF_STREAM))

#define IETF_STREAM1 (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_FIN_BIT)

#define IETF_STREAM2 (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_LEN_BIT)

#define IETF_STREAM3                                    \
  (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_LEN_BIT | \
   IETF_STREAM_FRAME_FIN_BIT)

#define IETF_STREAM4 (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_OFF_BIT)

#define IETF_STREAM5                                    \
  (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_OFF_BIT | \
   IETF_STREAM_FRAME_FIN_BIT)

#define IETF_STREAM6                                    \
  (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_OFF_BIT | \
   IETF_STREAM_FRAME_LEN_BIT)

#define IETF_STREAM7                                    \
  (((uint8_t)IETF_STREAM) | IETF_STREAM_FRAME_OFF_BIT | \
   IETF_STREAM_FRAME_LEN_BIT | IETF_STREAM_FRAME_FIN_BIT)

    {kStreamId8, kOffset8, true, false, IETF_STREAM7},
    {kStreamId8, kOffset8, false, false, IETF_STREAM6},
    {kStreamId8, kOffset4, true, false, IETF_STREAM7},
    {kStreamId8, kOffset4, false, false, IETF_STREAM6},
    {kStreamId8, kOffset2, true, false, IETF_STREAM7},
    {kStreamId8, kOffset2, false, false, IETF_STREAM6},
    {kStreamId8, kOffset1, true, false, IETF_STREAM7},
    {kStreamId8, kOffset1, false, false, IETF_STREAM6},
    {kStreamId8, kOffset0, true, false, IETF_STREAM3},
    {kStreamId8, kOffset0, false, false, IETF_STREAM2},
    {kStreamId4, kOffset8, true, false, IETF_STREAM7},
    {kStreamId4, kOffset8, false, false, IETF_STREAM6},
    {kStreamId4, kOffset4, true, false, IETF_STREAM7},
    {kStreamId4, kOffset4, false, false, IETF_STREAM6},
    {kStreamId4, kOffset2, true, false, IETF_STREAM7},
    {kStreamId4, kOffset2, false, false, IETF_STREAM6},
    {kStreamId4, kOffset1, true, false, IETF_STREAM7},
    {kStreamId4, kOffset1, false, false, IETF_STREAM6},
    {kStreamId4, kOffset0, true, false, IETF_STREAM3},
    {kStreamId4, kOffset0, false, false, IETF_STREAM2},
    {kStreamId2, kOffset8, true, false, IETF_STREAM7},
    {kStreamId2, kOffset8, false, false, IETF_STREAM6},
    {kStreamId2, kOffset4, true, false, IETF_STREAM7},
    {kStreamId2, kOffset4, false, false, IETF_STREAM6},
    {kStreamId2, kOffset2, true, false, IETF_STREAM7},
    {kStreamId2, kOffset2, false, false, IETF_STREAM6},
    {kStreamId2, kOffset1, true, false, IETF_STREAM7},
    {kStreamId2, kOffset1, false, false, IETF_STREAM6},
    {kStreamId2, kOffset0, true, false, IETF_STREAM3},
    {kStreamId2, kOffset0, false, false, IETF_STREAM2},
    {kStreamId1, kOffset8, true, false, IETF_STREAM7},
    {kStreamId1, kOffset8, false, false, IETF_STREAM6},
    {kStreamId1, kOffset4, true, false, IETF_STREAM7},
    {kStreamId1, kOffset4, false, false, IETF_STREAM6},
    {kStreamId1, kOffset2, true, false, IETF_STREAM7},
    {kStreamId1, kOffset2, false, false, IETF_STREAM6},
    {kStreamId1, kOffset1, true, false, IETF_STREAM7},
    {kStreamId1, kOffset1, false, false, IETF_STREAM6},
    {kStreamId1, kOffset0, true, false, IETF_STREAM3},
    {kStreamId1, kOffset0, false, false, IETF_STREAM2},
    {kStreamId0, kOffset8, true, false, IETF_STREAM7},
    {kStreamId0, kOffset8, false, false, IETF_STREAM6},
    {kStreamId0, kOffset4, true, false, IETF_STREAM7},
    {kStreamId0, kOffset4, false, false, IETF_STREAM6},
    {kStreamId0, kOffset2, true, false, IETF_STREAM7},
    {kStreamId0, kOffset2, false, false, IETF_STREAM6},
    {kStreamId0, kOffset1, true, false, IETF_STREAM7},
    {kStreamId0, kOffset1, false, false, IETF_STREAM6},
    {kStreamId0, kOffset0, true, false, IETF_STREAM3},
    {kStreamId0, kOffset0, false, false, IETF_STREAM2},

    {kStreamId8, kOffset8, true, true, IETF_STREAM5},
    {kStreamId8, kOffset8, false, true, IETF_STREAM4},
    {kStreamId8, kOffset4, true, true, IETF_STREAM5},
    {kStreamId8, kOffset4, false, true, IETF_STREAM4},
    {kStreamId8, kOffset2, true, true, IETF_STREAM5},
    {kStreamId8, kOffset2, false, true, IETF_STREAM4},
    {kStreamId8, kOffset1, true, true, IETF_STREAM5},
    {kStreamId8, kOffset1, false, true, IETF_STREAM4},
    {kStreamId8, kOffset0, true, true, IETF_STREAM1},
    {kStreamId8, kOffset0, false, true, IETF_STREAM0},
    {kStreamId4, kOffset8, true, true, IETF_STREAM5},
    {kStreamId4, kOffset8, false, true, IETF_STREAM4},
    {kStreamId4, kOffset4, true, true, IETF_STREAM5},
    {kStreamId4, kOffset4, false, true, IETF_STREAM4},
    {kStreamId4, kOffset2, true, true, IETF_STREAM5},
    {kStreamId4, kOffset2, false, true, IETF_STREAM4},
    {kStreamId4, kOffset1, true, true, IETF_STREAM5},
    {kStreamId4, kOffset1, false, true, IETF_STREAM4},
    {kStreamId4, kOffset0, true, true, IETF_STREAM1},
    {kStreamId4, kOffset0, false, true, IETF_STREAM0},
    {kStreamId2, kOffset8, true, true, IETF_STREAM5},
    {kStreamId2, kOffset8, false, true, IETF_STREAM4},
    {kStreamId2, kOffset4, true, true, IETF_STREAM5},
    {kStreamId2, kOffset4, false, true, IETF_STREAM4},
    {kStreamId2, kOffset2, true, true, IETF_STREAM5},
    {kStreamId2, kOffset2, false, true, IETF_STREAM4},
    {kStreamId2, kOffset1, true, true, IETF_STREAM5},
    {kStreamId2, kOffset1, false, true, IETF_STREAM4},
    {kStreamId2, kOffset0, true, true, IETF_STREAM1},
    {kStreamId2, kOffset0, false, true, IETF_STREAM0},
    {kStreamId1, kOffset8, true, true, IETF_STREAM5},
    {kStreamId1, kOffset8, false, true, IETF_STREAM4},
    {kStreamId1, kOffset4, true, true, IETF_STREAM5},
    {kStreamId1, kOffset4, false, true, IETF_STREAM4},
    {kStreamId1, kOffset2, true, true, IETF_STREAM5},
    {kStreamId1, kOffset2, false, true, IETF_STREAM4},
    {kStreamId1, kOffset1, true, true, IETF_STREAM5},
    {kStreamId1, kOffset1, false, true, IETF_STREAM4},
    {kStreamId1, kOffset0, true, true, IETF_STREAM1},
    {kStreamId1, kOffset0, false, true, IETF_STREAM0},
    {kStreamId0, kOffset8, true, true, IETF_STREAM5},
    {kStreamId0, kOffset8, false, true, IETF_STREAM4},
    {kStreamId0, kOffset4, true, true, IETF_STREAM5},
    {kStreamId0, kOffset4, false, true, IETF_STREAM4},
    {kStreamId0, kOffset2, true, true, IETF_STREAM5},
    {kStreamId0, kOffset2, false, true, IETF_STREAM4},
    {kStreamId0, kOffset1, true, true, IETF_STREAM5},
    {kStreamId0, kOffset1, false, true, IETF_STREAM4},
    {kStreamId0, kOffset0, true, true, IETF_STREAM1},
    {kStreamId0, kOffset0, false, true, IETF_STREAM0},
};

TEST_F(QuicIetfFramerTest, StreamFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  const char* transmit_packet_data =
      "this is a test of some packet data, "
      "can do a simple strcmp to see if the "
      "input and output are the same!";

  size_t transmit_packet_data_len = strlen(transmit_packet_data) + 1;
  for (size_t i = 0; i < QUIC_ARRAYSIZE(stream_frame_to_test); ++i) {
    SCOPED_TRACE(i);
    struct stream_frame_variant* variant = &stream_frame_to_test[i];
    TryStreamFrame(packet_buffer, sizeof(packet_buffer), transmit_packet_data,
                   transmit_packet_data_len, variant->stream_id,
                   variant->offset, variant->fin_bit, variant->last_frame_bit,
                   static_cast<QuicIetfFrameType>(variant->frame_type));
  }
}
// As the previous test, but with no data.
TEST_F(QuicIetfFramerTest, ZeroLengthStreamFrame) {
  char packet_buffer[kNormalPacketBufferSize];

  for (size_t i = 0; i < QUIC_ARRAYSIZE(stream_frame_to_test); ++i) {
    SCOPED_TRACE(i);
    struct stream_frame_variant* variant = &stream_frame_to_test[i];
    TryStreamFrame(packet_buffer, sizeof(packet_buffer),
                   /* xmit_packet_data = */ NULL,
                   /* xmit_packet_data_size = */ 0, variant->stream_id,
                   variant->offset, variant->fin_bit, variant->last_frame_bit,
                   static_cast<QuicIetfFrameType>(variant->frame_type));
  }
}

TEST_F(QuicIetfFramerTest, CryptoFrame) {
  SimpleDataProducer data_producer;
  framer_.set_data_producer(&data_producer);
  char packet_buffer[kNormalPacketBufferSize];

  QuicStringPiece frame_data("This is a CRYPTO frame.");

  QuicStreamOffset offsets[] = {kOffset8, kOffset4, kOffset2, kOffset1,
                                kOffset0};
  for (QuicStreamOffset offset : offsets) {
    QuicCryptoFrame frame(ENCRYPTION_NONE, offset, frame_data.length());
    data_producer.SaveCryptoData(ENCRYPTION_NONE, offset, frame_data);

    QuicDataWriter writer(QUIC_ARRAYSIZE(packet_buffer), packet_buffer,
                          NETWORK_BYTE_ORDER);

    // Write the frame.
    EXPECT_TRUE(QuicFramerPeer::AppendCryptoFrame(&framer_, frame, &writer));
    EXPECT_NE(0u, writer.length());
    // Read it back.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
    QuicCryptoFrame read_frame;
    EXPECT_TRUE(
        QuicFramerPeer::ProcessCryptoFrame(&framer_, &reader, &read_frame));

    // Check that the frames match:
    QuicStringPiece read_data(read_frame.data_buffer, read_frame.data_length);
    EXPECT_EQ(read_frame.data_length, frame.data_length);
    EXPECT_EQ(read_frame.offset, frame.offset);
    EXPECT_EQ(read_data, frame_data);
  }
}

TEST_F(QuicIetfFramerTest, ConnectionCloseEmptyString) {
  char packet_buffer[kNormalPacketBufferSize];

  // initialize a writer so that the serialized packet is placed in
  // packet_buffer.
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  // empty string,
  QuicString test_string = "Ich Bin Ein Jelly Donut?";
  QuicConnectionCloseFrame sent_frame;
  sent_frame.error_code = static_cast<QuicErrorCode>(0);
  sent_frame.error_details = test_string;
  sent_frame.frame_type = 123;
  // write the frame to the packet buffer.
  EXPECT_TRUE(QuicFramerPeer::AppendIetfConnectionCloseFrame(
      &framer_, sent_frame, &writer));

  // better have something in the packet buffer.
  EXPECT_NE(0u, writer.length());

  // now set up a reader to read in the frame.
  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

  // a QuicConnectionCloseFrame to hold the results.
  QuicConnectionCloseFrame sink_frame;

  EXPECT_TRUE(QuicFramerPeer::ProcessIetfConnectionCloseFrame(&framer_, &reader,
                                                              &sink_frame));

  // Now check that received == sent
  EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
  EXPECT_EQ(sink_frame.error_details, test_string);
}

TEST_F(QuicIetfFramerTest, ApplicationCloseEmptyString) {
  char packet_buffer[kNormalPacketBufferSize];

  // initialize a writer so that the serialized packet is placed in
  // packet_buffer.
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  // empty string,
  QuicString test_string = "Ich Bin Ein Jelly Donut?";
  QuicApplicationCloseFrame sent_frame;
  sent_frame.error_code = static_cast<QuicErrorCode>(0);
  sent_frame.error_details = test_string;
  // write the frame to the packet buffer.
  EXPECT_TRUE(QuicFramerPeer::AppendApplicationCloseFrame(&framer_, sent_frame,
                                                          &writer));

  // better have something in the packet buffer.
  EXPECT_NE(0u, writer.length());

  // now set up a reader to read in the frame.
  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

  // a QuicConnectionCloseFrame to hold the results.
  QuicApplicationCloseFrame sink_frame;

  EXPECT_TRUE(QuicFramerPeer::ProcessApplicationCloseFrame(&framer_, &reader,
                                                           &sink_frame));

  // Now check that received == sent
  EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
  EXPECT_EQ(sink_frame.error_details, test_string);
}

// Testing for the IETF ACK framer.
// clang-format off
struct ack_frame ack_frame_variants[] = {
    {90000,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1000), QuicPacketNumber(2001)}},
     IETF_ACK},
    {0,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1000), QuicPacketNumber(2001)}},
     IETF_ACK},
    {1,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(2)},
      {QuicPacketNumber(5), QuicPacketNumber(6)}},
     IETF_ACK},
    {63,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(2)},
      {QuicPacketNumber(5), QuicPacketNumber(6)}},
     IETF_ACK},
    {64,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(2)},
      {QuicPacketNumber(3), QuicPacketNumber(4)},
      {QuicPacketNumber(5), QuicPacketNumber(6)},
      {QuicPacketNumber(7), QuicPacketNumber(8)},
      {QuicPacketNumber(9), QuicPacketNumber(10)},
      {QuicPacketNumber(11), QuicPacketNumber(12)}},
     IETF_ACK},
    {10000,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(2)},
      {QuicPacketNumber(3), QuicPacketNumber(4)},
      {QuicPacketNumber(5), QuicPacketNumber(6)},
      {QuicPacketNumber(7), QuicPacketNumber(8)},
      {QuicPacketNumber(9), QuicPacketNumber(10)},
      {QuicPacketNumber(11), QuicPacketNumber(12)}},
     IETF_ACK},
    {100000000,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(2)},
      {QuicPacketNumber(3), QuicPacketNumber(4)},
      {QuicPacketNumber(5), QuicPacketNumber(6)},
      {QuicPacketNumber(7), QuicPacketNumber(8)},
      {QuicPacketNumber(9), QuicPacketNumber(10)},
      {QuicPacketNumber(11), QuicPacketNumber(12)}},
     IETF_ACK},
    {0,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)}},
     IETF_ACK},
    {9223372036854775807,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(11)},
      {QuicPacketNumber(74), QuicPacketNumber(138)}},
     IETF_ACK},
    // This ack is for packets 60 & 125. There are 64 packets in the gap.
    // The encoded value is gap_size - 1, or 63. Crosses a VarInt62 encoding
    // boundary...
    {1,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(60), QuicPacketNumber(61)},
      {QuicPacketNumber(125), QuicPacketNumber(126)}},
     IETF_ACK},
    {2,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(130)}},
     IETF_ACK},
    {3,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(195)}},
     IETF_ACK},
    {4,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(194)}},
     IETF_ACK},
    {5,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(193)}},
     IETF_ACK},
    {6,
     false,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK},
    // declare some ack_ecn frames to try.
    {6,
     false,
     100,
     200,
     300,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK},
    {6,
     true,
     100,
     200,
     300,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK_ECN},
    {6,
     true,
     100,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK_ECN},
    {6,
     true,
     0,
     200,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK_ECN},
    {6,
     true,
     0,
     0,
     300,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK_ECN},
    {6,
     true,
     0,
     0,
     0,
     {{QuicPacketNumber(1), QuicPacketNumber(65)},
      {QuicPacketNumber(129), QuicPacketNumber(192)}},
     IETF_ACK},
};
// clang-format on

TEST_F(QuicIetfFramerTest, AckFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  for (auto ack_frame_variant : ack_frame_variants) {
    EXPECT_TRUE(
        TryAckFrame(packet_buffer, sizeof(packet_buffer), &ack_frame_variant));
  }
}

// Test the case of having a QuicAckFrame with no ranges in it.  By
// examination of the Google Quic Ack code and tests, this case should
// be handled as an ack with no "ranges after the first"; the
// AckBlockCount should be 0 and the FirstAckBlock should be
// |LargestAcked| - 1 (number of packets preceding the LargestAcked.
TEST_F(QuicIetfFramerTest, AckFrameNoRanges) {
  char packet_buffer[kNormalPacketBufferSize];

  // Make a writer so that the serialized packet is placed in
  // packet_buffer.
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  QuicAckFrame transmit_frame;
  transmit_frame.largest_acked = QuicPacketNumber(1);
  transmit_frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(0);

  size_t expected_size =
      QuicFramerPeer::GetIetfAckFrameSize(&framer_, transmit_frame);
  // Write the frame to the packet buffer.
  EXPECT_TRUE(QuicFramerPeer::AppendIetfAckFrameAndTypeByte(
      &framer_, transmit_frame, &writer));

  uint8_t packet[] = {
      0x02,  // type, IETF_ACK
      0x01,  // largest_acked,
      0x00,  // delay
      0x00,  // count of additional ack blocks
      0x00,  // size of first ack block (packets preceding largest_acked)
  };
  EXPECT_EQ(expected_size, sizeof(packet));
  EXPECT_EQ(sizeof(packet), writer.length());
  EXPECT_EQ(0, memcmp(packet, packet_buffer, writer.length()));

  // Now set up a reader to read in the frame.
  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

  // an AckFrame to hold the results
  QuicAckFrame receive_frame;

  // read in the frame type
  uint8_t received_frame_type;
  EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
  EXPECT_EQ(received_frame_type, IETF_ACK);

  EXPECT_TRUE(QuicFramerPeer::ProcessIetfAckFrame(&framer_, &reader, IETF_ACK,
                                                  &receive_frame));

  // Now check that the received frame matches the sent frame.
  EXPECT_EQ(transmit_frame.largest_acked, receive_frame.largest_acked);
}

TEST_F(QuicIetfFramerTest, PathChallengeFrame) {
  // Double-braces needed on some platforms due to
  // https://bugs.llvm.org/show_bug.cgi?id=21629
  QuicPathFrameBuffer buffer0 = {{0, 0, 0, 0, 0, 0, 0, 0}};
  QuicPathFrameBuffer buffer1 = {
      {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
  char packet_buffer[kNormalPacketBufferSize];
  EXPECT_TRUE(
      TryPathChallengeFrame(packet_buffer, sizeof(packet_buffer), buffer0));
  EXPECT_TRUE(
      TryPathChallengeFrame(packet_buffer, sizeof(packet_buffer), buffer1));
}

TEST_F(QuicIetfFramerTest, PathResponseFrame) {
  // Double-braces needed on some platforms due to
  // https://bugs.llvm.org/show_bug.cgi?id=21629
  QuicPathFrameBuffer buffer0 = {{0, 0, 0, 0, 0, 0, 0, 0}};
  QuicPathFrameBuffer buffer1 = {
      {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
  char packet_buffer[kNormalPacketBufferSize];
  EXPECT_TRUE(
      TryPathResponseFrame(packet_buffer, sizeof(packet_buffer), buffer0));
  EXPECT_TRUE(
      TryPathResponseFrame(packet_buffer, sizeof(packet_buffer), buffer1));
}

TEST_F(QuicIetfFramerTest, ResetStreamFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  struct resets {
    QuicStreamId stream_id;
    uint16_t error_code;
    QuicStreamOffset final_offset;
  } reset_frames[] = {
      {0, 55, 0},
      {0x10, 73, 0x300},
  };
  for (auto reset : reset_frames) {
    TryResetFrame(packet_buffer, sizeof(packet_buffer), reset.stream_id,
                  reset.error_code, reset.final_offset);
  }
}

TEST_F(QuicIetfFramerTest, StopSendingFrame) {
  char packet_buffer[kNormalPacketBufferSize];

  // Make a writer so that the serialized packet is placed in
  // packet_buffer.
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  QuicStopSendingFrame transmit_frame;
  transmit_frame.stream_id = 12345;
  transmit_frame.application_error_code = 543;

  // Write the frame to the packet buffer.
  EXPECT_TRUE(QuicFramerPeer::AppendStopSendingFrame(&framer_, transmit_frame,
                                                     &writer));
  // Check that the number of bytes in the buffer is in the
  // allowed range.
  EXPECT_LE(3u, writer.length());
  EXPECT_GE(10u, writer.length());

  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);

  // A frame to hold the results
  QuicStopSendingFrame receive_frame;

  EXPECT_TRUE(QuicFramerPeer::ProcessStopSendingFrame(&framer_, &reader,
                                                      &receive_frame));

  // Verify that the transmitted and received values are the same.
  EXPECT_EQ(receive_frame.stream_id, 12345u);
  EXPECT_EQ(receive_frame.application_error_code, 543u);
  EXPECT_EQ(receive_frame.stream_id, transmit_frame.stream_id);
  EXPECT_EQ(receive_frame.application_error_code,
            transmit_frame.application_error_code);
}

TEST_F(QuicIetfFramerTest, MaxDataFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  QuicStreamOffset window_sizes[] = {0,       1,        2,        5,       10,
                                     20,      50,       100,      200,     500,
                                     1000000, kOffset8, kOffset4, kOffset2};
  for (QuicStreamOffset window_size : window_sizes) {
    memset(packet_buffer, 0, sizeof(packet_buffer));

    // Set up the writer and transmit QuicWindowUpdateFrame
    QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                          NETWORK_BYTE_ORDER);
    QuicWindowUpdateFrame transmit_frame(0, 99, window_size);

    // Add the frame.
    EXPECT_TRUE(
        QuicFramerPeer::AppendMaxDataFrame(&framer_, transmit_frame, &writer));

    // Check that the number of bytes in the buffer is in the expected range.
    EXPECT_LE(1u, writer.length());
    EXPECT_GE(8u, writer.length());

    // Set up reader and an empty QuicWindowUpdateFrame
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
    QuicWindowUpdateFrame receive_frame;

    // Deframe it
    EXPECT_TRUE(
        QuicFramerPeer::ProcessMaxDataFrame(&framer_, &reader, &receive_frame));

    // Now check that the received data equals the sent data.
    EXPECT_EQ(transmit_frame.byte_offset, window_size);
    EXPECT_EQ(transmit_frame.byte_offset, receive_frame.byte_offset);
    EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
              receive_frame.stream_id);
  }
}

TEST_F(QuicIetfFramerTest, MaxStreamDataFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  QuicStreamOffset window_sizes[] = {0,       1,        2,        5,       10,
                                     20,      50,       100,      200,     500,
                                     1000000, kOffset8, kOffset4, kOffset2};
  QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
                                   kStreamId0};

  for (QuicIetfStreamId stream_id : stream_ids) {
    for (QuicStreamOffset window_size : window_sizes) {
      memset(packet_buffer, 0, sizeof(packet_buffer));

      // Set up the writer and transmit QuicWindowUpdateFrame
      QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                            NETWORK_BYTE_ORDER);
      QuicWindowUpdateFrame transmit_frame(0, stream_id, window_size);

      // Add the frame.
      EXPECT_TRUE(QuicFramerPeer::AppendMaxStreamDataFrame(
          &framer_, transmit_frame, &writer));

      // Check that number of bytes in the buffer is in the expected range.
      EXPECT_LE(2u, writer.length());
      EXPECT_GE(16u, writer.length());

      // Set up reader and empty receive QuicPaddingFrame.
      QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
      QuicWindowUpdateFrame receive_frame;

      // Deframe it
      EXPECT_TRUE(QuicFramerPeer::ProcessMaxStreamDataFrame(&framer_, &reader,
                                                            &receive_frame));

      // Now check that received data and sent data are equal.
      EXPECT_EQ(transmit_frame.byte_offset, window_size);
      EXPECT_EQ(transmit_frame.byte_offset, receive_frame.byte_offset);
      EXPECT_EQ(stream_id, receive_frame.stream_id);
      EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
    }
  }
}

TEST_F(QuicIetfFramerTest, MaxStreamsFrame) {
  QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
                                   kStreamId0};

  for (QuicIetfStreamId stream_id : stream_ids) {
    // Cover all four combinations of uni/bi-directional and
    // server-/client- initiation.
    TryMaxStreamsFrame(stream_id, /*unidirectional=*/true,
                       /*stream_id_server_initiated=*/true);
    TryMaxStreamsFrame(stream_id, /*unidirectional=*/true,
                       /*stream_id_server_initiated=*/false);
    TryMaxStreamsFrame(stream_id, /*unidirectional=*/false,
                       /*stream_id_server_initiated=*/true);
    TryMaxStreamsFrame(stream_id, /*unidirectional=*/false,
                       /*stream_id_server_initiated=*/false);
  }
}

TEST_F(QuicIetfFramerTest, BlockedFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  QuicStreamOffset offsets[] = {kOffset8, kOffset4, kOffset2, kOffset1,
                                kOffset0};

  for (QuicStreamOffset offset : offsets) {
    memset(packet_buffer, 0, sizeof(packet_buffer));

    // Set up the writer and transmit QuicBlockedFrame
    QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                          NETWORK_BYTE_ORDER);
    QuicBlockedFrame transmit_frame(
        0, QuicUtils::GetInvalidStreamId(framer_.transport_version()), offset);

    // Add the frame.
    EXPECT_TRUE(QuicFramerPeer::AppendIetfBlockedFrame(&framer_, transmit_frame,
                                                       &writer));

    // Check that buffer length is in the expected range
    EXPECT_LE(1u, writer.length());
    EXPECT_GE(8u, writer.length());

    // Set up reader and empty receive QuicFrame.
    QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
    QuicBlockedFrame receive_frame;

    // Deframe it
    EXPECT_TRUE(QuicFramerPeer::ProcessIetfBlockedFrame(&framer_, &reader,
                                                        &receive_frame));

    // Check that received and sent data are equivalent
    EXPECT_EQ(QuicUtils::GetInvalidStreamId(framer_.transport_version()),
              receive_frame.stream_id);
    EXPECT_EQ(offset, receive_frame.offset);
    EXPECT_EQ(transmit_frame.offset, receive_frame.offset);
  }
}

TEST_F(QuicIetfFramerTest, StreamBlockedFrame) {
  char packet_buffer[kNormalPacketBufferSize];
  QuicStreamOffset offsets[] = {0,       1,        2,        5,       10,
                                20,      50,       100,      200,     500,
                                1000000, kOffset8, kOffset4, kOffset2};
  QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
                                   kStreamId0};

  for (QuicIetfStreamId stream_id : stream_ids) {
    for (QuicStreamOffset offset : offsets) {
      memset(packet_buffer, 0, sizeof(packet_buffer));

      // Set up the writer and transmit QuicWindowUpdateFrame
      QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                            NETWORK_BYTE_ORDER);
      QuicBlockedFrame transmit_frame(0, stream_id, offset);

      // Add the frame.
      EXPECT_TRUE(QuicFramerPeer::AppendStreamBlockedFrame(
          &framer_, transmit_frame, &writer));

      // Check that number of bytes in the buffer is in the expected range.
      EXPECT_LE(2u, writer.length());
      EXPECT_GE(16u, writer.length());

      // Set up reader and empty receive QuicPaddingFrame.
      QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
      QuicBlockedFrame receive_frame;

      // Deframe it
      EXPECT_TRUE(QuicFramerPeer::ProcessStreamBlockedFrame(&framer_, &reader,
                                                            &receive_frame));

      // Now check that received == sent
      EXPECT_EQ(transmit_frame.offset, offset);
      EXPECT_EQ(transmit_frame.offset, receive_frame.offset);
      EXPECT_EQ(stream_id, receive_frame.stream_id);
      EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
    }
  }
}

TEST_F(QuicIetfFramerTest, StreamsBlockedFrame) {
  QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
                                   kStreamId0};

  for (QuicIetfStreamId stream_id : stream_ids) {
    TryStreamsBlockedFrame(stream_id,
                           /*unidirectional=*/false,
                           /*stream_id_server_initiated=*/false);
    TryStreamsBlockedFrame(stream_id,
                           /*unidirectional=*/false,
                           /*stream_id_server_initiated=*/true);
    TryStreamsBlockedFrame(stream_id,
                           /*unidirectional=*/true,
                           /*stream_id_server_initiated=*/false);
    TryStreamsBlockedFrame(stream_id,
                           /*unidirectional=*/true,
                           /*stream_id_server_initiated=*/true);
  }
}

TEST_F(QuicIetfFramerTest, NewConnectionIdFrame) {
  char packet_buffer[kNormalPacketBufferSize];

  QuicNewConnectionIdFrame transmit_frame;
  transmit_frame.connection_id = TestConnectionId(UINT64_C(0x0edcba9876543201));
  transmit_frame.sequence_number = 0x01020304;
  // The token is defined as a uint128 -- a 16-byte integer.
  // The value is set in this manner because we want each
  // byte to have a specific value so that the binary
  // packet check (below) is good. If we used integer
  // operations (eg. "token = 0x12345...") then the bytes
  // would be set in host order.
  unsigned char token_bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
                                 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
                                 0x0c, 0x0d, 0x0e, 0x0f};
  memcpy(&transmit_frame.stateless_reset_token, token_bytes,
         sizeof(transmit_frame.stateless_reset_token));

  memset(packet_buffer, 0, sizeof(packet_buffer));

  // Set up the writer and transmit QuicStreamIdBlockedFrame
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  // Add the frame.
  EXPECT_TRUE(QuicFramerPeer::AppendNewConnectionIdFrame(
      &framer_, transmit_frame, &writer));
  // Check that buffer length is correct
  EXPECT_EQ(29u, writer.length());
  // clang-format off
  uint8_t packet[] = {
    // sequence number, 0x80 for varint62 encoding
    0x80 + 0x01, 0x02, 0x03, 0x04,
    // new connection id length, is not varint62 encoded.
    0x08,
    // new connection id, is not varint62 encoded.
    0x0E, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x01,
    // the reset token:
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  };

  // clang-format on
  EXPECT_EQ(0, memcmp(packet_buffer, packet, sizeof(packet)));

  // Set up reader and empty receive QuicPaddingFrame.
  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
  QuicNewConnectionIdFrame receive_frame;

  // Deframe it
  EXPECT_TRUE(QuicFramerPeer::ProcessNewConnectionIdFrame(&framer_, &reader,
                                                          &receive_frame));

  // Now check that received == sent
  EXPECT_EQ(transmit_frame.connection_id, receive_frame.connection_id);
  EXPECT_EQ(transmit_frame.sequence_number, receive_frame.sequence_number);
  EXPECT_EQ(transmit_frame.stateless_reset_token,
            receive_frame.stateless_reset_token);
}

TEST_F(QuicIetfFramerTest, RetireConnectionIdFrame) {
  char packet_buffer[kNormalPacketBufferSize];

  QuicRetireConnectionIdFrame transmit_frame;
  transmit_frame.sequence_number = 0x01020304;

  memset(packet_buffer, 0, sizeof(packet_buffer));

  // Set up the writer and transmit QuicStreamIdBlockedFrame
  QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
                        NETWORK_BYTE_ORDER);

  // Add the frame.
  EXPECT_TRUE(QuicFramerPeer::AppendRetireConnectionIdFrame(
      &framer_, transmit_frame, &writer));
  // Check that buffer length is correct
  EXPECT_EQ(4u, writer.length());
  // clang-format off
  uint8_t packet[] = {
    // sequence number, 0x80 for varint62 encoding
    0x80 + 0x01, 0x02, 0x03, 0x04,
  };

  // clang-format on
  EXPECT_EQ(0, memcmp(packet_buffer, packet, sizeof(packet)));

  // Set up reader and empty receive QuicPaddingFrame.
  QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
  QuicRetireConnectionIdFrame receive_frame;

  // Deframe it
  EXPECT_TRUE(QuicFramerPeer::ProcessRetireConnectionIdFrame(&framer_, &reader,
                                                             &receive_frame));

  // Now check that received == sent
  EXPECT_EQ(transmit_frame.sequence_number, receive_frame.sequence_number);
}

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