blob: 671e7724014dcefc67d50ed9d628a56707b5f1fd [file] [log] [blame]
// Copyright (c) 2016 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 "quiche/quic/core/frames/quic_ack_frame.h"
#include "quiche/quic/core/frames/quic_blocked_frame.h"
#include "quiche/quic/core/frames/quic_connection_close_frame.h"
#include "quiche/quic/core/frames/quic_frame.h"
#include "quiche/quic/core/frames/quic_goaway_frame.h"
#include "quiche/quic/core/frames/quic_mtu_discovery_frame.h"
#include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
#include "quiche/quic/core/frames/quic_padding_frame.h"
#include "quiche/quic/core/frames/quic_ping_frame.h"
#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
#include "quiche/quic/core/frames/quic_stop_waiting_frame.h"
#include "quiche/quic/core/frames/quic_stream_frame.h"
#include "quiche/quic/core/frames/quic_window_update_frame.h"
#include "quiche/quic/core/quic_interval.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"
namespace quic {
namespace test {
namespace {
class QuicFramesTest : public QuicTest {};
TEST_F(QuicFramesTest, AckFrameToString) {
QuicAckFrame frame;
frame.largest_acked = QuicPacketNumber(5);
frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
frame.packets.Add(QuicPacketNumber(4));
frame.packets.Add(QuicPacketNumber(5));
frame.received_packet_times = {
{QuicPacketNumber(6),
QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
std::ostringstream stream;
stream << frame;
EXPECT_EQ(
"{ largest_acked: 5, ack_delay_time: 3, packets: [ 4 5 ], "
"received_packets: [ 6 at 7 ], ecn_counters_populated: 0 }\n",
stream.str());
QuicFrame quic_frame(&frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, BigAckFrameToString) {
QuicAckFrame frame;
frame.largest_acked = QuicPacketNumber(500);
frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
frame.received_packet_times = {
{QuicPacketNumber(500),
QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
std::ostringstream stream;
stream << frame;
EXPECT_EQ(
"{ largest_acked: 500, ack_delay_time: 3, packets: [ 4...500 ], "
"received_packets: [ 500 at 7 ], ecn_counters_populated: 0 }\n",
stream.str());
QuicFrame quic_frame(&frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, PaddingFrameToString) {
QuicPaddingFrame frame;
frame.num_padding_bytes = 1;
std::ostringstream stream;
stream << frame;
EXPECT_EQ("{ num_padding_bytes: 1 }\n", stream.str());
QuicFrame quic_frame(frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, RstStreamFrameToString) {
QuicRstStreamFrame rst_stream;
QuicFrame frame(&rst_stream);
SetControlFrameId(1, &frame);
EXPECT_EQ(1u, GetControlFrameId(frame));
rst_stream.stream_id = 1;
rst_stream.byte_offset = 3;
rst_stream.error_code = QUIC_STREAM_CANCELLED;
std::ostringstream stream;
stream << rst_stream;
EXPECT_EQ(
"{ control_frame_id: 1, stream_id: 1, byte_offset: 3, error_code: 6, "
"ietf_error_code: 0 }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, StopSendingFrameToString) {
QuicFrame frame((QuicStopSendingFrame()));
SetControlFrameId(1, &frame);
EXPECT_EQ(1u, GetControlFrameId(frame));
frame.stop_sending_frame.stream_id = 321;
frame.stop_sending_frame.error_code = QUIC_STREAM_CANCELLED;
frame.stop_sending_frame.ietf_error_code =
static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
std::ostringstream stream;
stream << frame.stop_sending_frame;
EXPECT_EQ(
"{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
"268 }\n",
stream.str());
}
TEST_F(QuicFramesTest, NewConnectionIdFrameToString) {
QuicNewConnectionIdFrame new_connection_id_frame;
QuicFrame frame(&new_connection_id_frame);
SetControlFrameId(1, &frame);
QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
EXPECT_EQ(1u, GetControlFrameId(frame_copy));
new_connection_id_frame.connection_id = TestConnectionId(2);
new_connection_id_frame.sequence_number = 2u;
new_connection_id_frame.retire_prior_to = 1u;
new_connection_id_frame.stateless_reset_token =
StatelessResetToken{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
std::ostringstream stream;
stream << new_connection_id_frame;
EXPECT_EQ(
"{ control_frame_id: 1, connection_id: 0000000000000002, "
"sequence_number: 2, retire_prior_to: 1 }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame_copy.type));
DeleteFrame(&frame_copy);
}
TEST_F(QuicFramesTest, RetireConnectionIdFrameToString) {
QuicRetireConnectionIdFrame retire_connection_id_frame;
QuicFrame frame(&retire_connection_id_frame);
SetControlFrameId(1, &frame);
QuicFrame frame_copy = CopyRetransmittableControlFrame(frame);
EXPECT_EQ(1u, GetControlFrameId(frame_copy));
retire_connection_id_frame.sequence_number = 1u;
std::ostringstream stream;
stream << retire_connection_id_frame;
EXPECT_EQ("{ control_frame_id: 1, sequence_number: 1 }\n", stream.str());
EXPECT_TRUE(IsControlFrame(frame_copy.type));
DeleteFrame(&frame_copy);
}
TEST_F(QuicFramesTest, StreamsBlockedFrameToString) {
QuicStreamsBlockedFrame streams_blocked;
QuicFrame frame(streams_blocked);
SetControlFrameId(1, &frame);
EXPECT_EQ(1u, GetControlFrameId(frame));
// QuicStreamsBlocked is copied into a QuicFrame (as opposed to putting a
// pointer to it into QuicFrame) so need to work with the copy in |frame| and
// not the original one, streams_blocked.
frame.streams_blocked_frame.stream_count = 321;
frame.streams_blocked_frame.unidirectional = false;
std::ostringstream stream;
stream << frame.streams_blocked_frame;
EXPECT_EQ("{ control_frame_id: 1, stream count: 321, bidirectional }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, MaxStreamsFrameToString) {
QuicMaxStreamsFrame max_streams;
QuicFrame frame(max_streams);
SetControlFrameId(1, &frame);
EXPECT_EQ(1u, GetControlFrameId(frame));
// QuicMaxStreams is copied into a QuicFrame (as opposed to putting a
// pointer to it into QuicFrame) so need to work with the copy in |frame| and
// not the original one, max_streams.
frame.max_streams_frame.stream_count = 321;
frame.max_streams_frame.unidirectional = true;
std::ostringstream stream;
stream << frame.max_streams_frame;
EXPECT_EQ("{ control_frame_id: 1, stream_count: 321, unidirectional }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, ConnectionCloseFrameToString) {
QuicConnectionCloseFrame frame;
frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
frame.error_details = "No recent network activity.";
std::ostringstream stream;
stream << frame;
// Note that "extracted_error_code: 122" is QUIC_IETF_GQUIC_ERROR_MISSING,
// indicating that, in fact, no extended error code was available from the
// underlying frame.
EXPECT_EQ(
"{ Close type: GOOGLE_QUIC_CONNECTION_CLOSE, "
"quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
"error_details: 'No recent network activity.'}\n",
stream.str());
QuicFrame quic_frame(&frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, TransportConnectionCloseFrameToString) {
QuicConnectionCloseFrame frame;
frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
frame.wire_error_code = FINAL_SIZE_ERROR;
frame.quic_error_code = QUIC_NETWORK_IDLE_TIMEOUT;
frame.error_details = "No recent network activity.";
frame.transport_close_frame_type = IETF_STREAM;
std::ostringstream stream;
stream << frame;
EXPECT_EQ(
"{ Close type: IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, "
"wire_error_code: FINAL_SIZE_ERROR, "
"quic_error_code: QUIC_NETWORK_IDLE_TIMEOUT, "
"error_details: 'No recent "
"network activity.', "
"frame_type: IETF_STREAM"
"}\n",
stream.str());
QuicFrame quic_frame(&frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, GoAwayFrameToString) {
QuicGoAwayFrame goaway_frame;
QuicFrame frame(&goaway_frame);
SetControlFrameId(2, &frame);
EXPECT_EQ(2u, GetControlFrameId(frame));
goaway_frame.error_code = QUIC_NETWORK_IDLE_TIMEOUT;
goaway_frame.last_good_stream_id = 2;
goaway_frame.reason_phrase = "Reason";
std::ostringstream stream;
stream << goaway_frame;
EXPECT_EQ(
"{ control_frame_id: 2, error_code: 25, last_good_stream_id: 2, "
"reason_phrase: "
"'Reason' }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, WindowUpdateFrameToString) {
QuicFrame frame((QuicWindowUpdateFrame()));
SetControlFrameId(3, &frame);
EXPECT_EQ(3u, GetControlFrameId(frame));
std::ostringstream stream;
frame.window_update_frame.stream_id = 1;
frame.window_update_frame.max_data = 2;
stream << frame.window_update_frame;
EXPECT_EQ("{ control_frame_id: 3, stream_id: 1, max_data: 2 }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, BlockedFrameToString) {
QuicFrame frame((QuicBlockedFrame()));
SetControlFrameId(4, &frame);
EXPECT_EQ(4u, GetControlFrameId(frame));
frame.blocked_frame.stream_id = 1;
frame.blocked_frame.offset = 2;
std::ostringstream stream;
stream << frame.blocked_frame;
EXPECT_EQ("{ control_frame_id: 4, stream_id: 1, offset: 2 }\n", stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, PingFrameToString) {
QuicPingFrame ping;
QuicFrame frame(ping);
SetControlFrameId(5, &frame);
EXPECT_EQ(5u, GetControlFrameId(frame));
std::ostringstream stream;
stream << frame.ping_frame;
EXPECT_EQ("{ control_frame_id: 5 }\n", stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, HandshakeDoneFrameToString) {
QuicHandshakeDoneFrame handshake_done;
QuicFrame frame(handshake_done);
SetControlFrameId(6, &frame);
EXPECT_EQ(6u, GetControlFrameId(frame));
std::ostringstream stream;
stream << frame.handshake_done_frame;
EXPECT_EQ("{ control_frame_id: 6 }\n", stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, QuicAckFreuqncyFrameToString) {
QuicAckFrequencyFrame ack_frequency_frame;
ack_frequency_frame.sequence_number = 1;
ack_frequency_frame.packet_tolerance = 2;
ack_frequency_frame.max_ack_delay = QuicTime::Delta::FromMilliseconds(25);
ack_frequency_frame.ignore_order = false;
QuicFrame frame(&ack_frequency_frame);
ASSERT_EQ(ACK_FREQUENCY_FRAME, frame.type);
SetControlFrameId(6, &frame);
EXPECT_EQ(6u, GetControlFrameId(frame));
std::ostringstream stream;
stream << *frame.ack_frequency_frame;
EXPECT_EQ(
"{ control_frame_id: 6, sequence_number: 1, packet_tolerance: 2, "
"max_ack_delay_ms: 25, ignore_order: 0 }\n",
stream.str());
EXPECT_TRUE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, StreamFrameToString) {
QuicStreamFrame frame;
frame.stream_id = 1;
frame.fin = false;
frame.offset = 2;
frame.data_length = 3;
std::ostringstream stream;
stream << frame;
EXPECT_EQ("{ stream_id: 1, fin: 0, offset: 2, length: 3 }\n", stream.str());
EXPECT_FALSE(IsControlFrame(frame.type));
}
TEST_F(QuicFramesTest, StopWaitingFrameToString) {
QuicStopWaitingFrame frame;
frame.least_unacked = QuicPacketNumber(2);
std::ostringstream stream;
stream << frame;
EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
QuicFrame quic_frame(frame);
EXPECT_FALSE(IsControlFrame(quic_frame.type));
}
TEST_F(QuicFramesTest, IsAwaitingPacket) {
QuicAckFrame ack_frame1;
ack_frame1.largest_acked = QuicPacketNumber(10u);
ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
EXPECT_TRUE(
IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
EXPECT_FALSE(
IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
ack_frame1.packets.Add(QuicPacketNumber(12));
EXPECT_TRUE(
IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
QuicAckFrame ack_frame2;
ack_frame2.largest_acked = QuicPacketNumber(100u);
ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
QuicPacketNumber(20u)));
EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
QuicPacketNumber(20u)));
EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
QuicPacketNumber(20u)));
ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
QuicPacketNumber(20u)));
}
TEST_F(QuicFramesTest, AddPacket) {
QuicAckFrame ack_frame1;
ack_frame1.packets.Add(QuicPacketNumber(1));
ack_frame1.packets.Add(QuicPacketNumber(99));
EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
expected_intervals.emplace_back(
QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(99), QuicPacketNumber(100)));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
ack_frame1.packets.Add(QuicPacketNumber(20));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
expected_intervals2.emplace_back(
QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(20), QuicPacketNumber(21)));
expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(99), QuicPacketNumber(100)));
EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(expected_intervals2, actual_intervals2);
ack_frame1.packets.Add(QuicPacketNumber(19));
ack_frame1.packets.Add(QuicPacketNumber(21));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
expected_intervals3.emplace_back(
QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(19), QuicPacketNumber(22)));
expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(99), QuicPacketNumber(100)));
EXPECT_EQ(expected_intervals3, actual_intervals3);
ack_frame1.packets.Add(QuicPacketNumber(20));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals3, actual_intervals4);
QuicAckFrame ack_frame2;
ack_frame2.packets.Add(QuicPacketNumber(20));
ack_frame2.packets.Add(QuicPacketNumber(40));
ack_frame2.packets.Add(QuicPacketNumber(60));
ack_frame2.packets.Add(QuicPacketNumber(10));
ack_frame2.packets.Add(QuicPacketNumber(80));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
ack_frame2.packets.begin(), ack_frame2.packets.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(10), QuicPacketNumber(11)));
expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(20), QuicPacketNumber(21)));
expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(40), QuicPacketNumber(41)));
expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(60), QuicPacketNumber(61)));
expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(80), QuicPacketNumber(81)));
EXPECT_EQ(expected_intervals5, actual_intervals5);
}
TEST_F(QuicFramesTest, AddInterval) {
QuicAckFrame ack_frame1;
ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals{
{QuicPacketNumber(1), QuicPacketNumber(10)},
{QuicPacketNumber(50), QuicPacketNumber(100)},
};
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
// Add a range in the middle.
ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2{
{QuicPacketNumber(1), QuicPacketNumber(10)},
{QuicPacketNumber(20), QuicPacketNumber(30)},
{QuicPacketNumber(50), QuicPacketNumber(100)},
};
EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
EXPECT_EQ(expected_intervals2, actual_intervals2);
// Add ranges at both ends.
QuicAckFrame ack_frame2;
ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
ack_frame2.packets.begin(), ack_frame2.packets.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8{
{QuicPacketNumber(10), QuicPacketNumber(15)},
{QuicPacketNumber(20), QuicPacketNumber(25)},
{QuicPacketNumber(40), QuicPacketNumber(45)},
{QuicPacketNumber(60), QuicPacketNumber(65)},
{QuicPacketNumber(80), QuicPacketNumber(85)},
};
EXPECT_EQ(expected_intervals8, actual_intervals8);
}
TEST_F(QuicFramesTest, AddAdjacentForward) {
QuicAckFrame ack_frame1;
ack_frame1.packets.Add(QuicPacketNumber(49));
ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(49), QuicPacketNumber(100)));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
}
TEST_F(QuicFramesTest, AddAdjacentReverse) {
QuicAckFrame ack_frame1;
ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
ack_frame1.packets.Add(QuicPacketNumber(49));
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(49), QuicPacketNumber(100)));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
}
TEST_F(QuicFramesTest, RemoveSmallestInterval) {
QuicAckFrame ack_frame1;
ack_frame1.largest_acked = QuicPacketNumber(100u);
ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
ack_frame1.packets.RemoveSmallestInterval();
EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
ack_frame1.packets.RemoveSmallestInterval();
EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
}
TEST_F(QuicFramesTest, CopyQuicFrames) {
QuicFrames frames;
QuicMessageFrame* message_frame =
new QuicMessageFrame(1, MemSliceFromString("message"));
// Construct a frame list.
for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
switch (i) {
case PADDING_FRAME:
frames.push_back(QuicFrame(QuicPaddingFrame(-1)));
break;
case RST_STREAM_FRAME:
frames.push_back(QuicFrame(new QuicRstStreamFrame()));
break;
case CONNECTION_CLOSE_FRAME:
frames.push_back(QuicFrame(new QuicConnectionCloseFrame()));
break;
case GOAWAY_FRAME:
frames.push_back(QuicFrame(new QuicGoAwayFrame()));
break;
case WINDOW_UPDATE_FRAME:
frames.push_back(QuicFrame(QuicWindowUpdateFrame()));
break;
case BLOCKED_FRAME:
frames.push_back(QuicFrame(QuicBlockedFrame()));
break;
case STOP_WAITING_FRAME:
frames.push_back(QuicFrame(QuicStopWaitingFrame()));
break;
case PING_FRAME:
frames.push_back(QuicFrame(QuicPingFrame()));
break;
case CRYPTO_FRAME:
frames.push_back(QuicFrame(new QuicCryptoFrame()));
break;
case STREAM_FRAME:
frames.push_back(QuicFrame(QuicStreamFrame()));
break;
case ACK_FRAME:
frames.push_back(QuicFrame(new QuicAckFrame()));
break;
case MTU_DISCOVERY_FRAME:
frames.push_back(QuicFrame(QuicMtuDiscoveryFrame()));
break;
case NEW_CONNECTION_ID_FRAME:
frames.push_back(QuicFrame(new QuicNewConnectionIdFrame()));
break;
case MAX_STREAMS_FRAME:
frames.push_back(QuicFrame(QuicMaxStreamsFrame()));
break;
case STREAMS_BLOCKED_FRAME:
frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
break;
case PATH_RESPONSE_FRAME:
frames.push_back(QuicFrame(QuicPathResponseFrame()));
break;
case PATH_CHALLENGE_FRAME:
frames.push_back(QuicFrame(QuicPathChallengeFrame()));
break;
case STOP_SENDING_FRAME:
frames.push_back(QuicFrame(QuicStopSendingFrame()));
break;
case MESSAGE_FRAME:
frames.push_back(QuicFrame(message_frame));
break;
case NEW_TOKEN_FRAME:
frames.push_back(QuicFrame(new QuicNewTokenFrame()));
break;
case RETIRE_CONNECTION_ID_FRAME:
frames.push_back(QuicFrame(new QuicRetireConnectionIdFrame()));
break;
case HANDSHAKE_DONE_FRAME:
frames.push_back(QuicFrame(QuicHandshakeDoneFrame()));
break;
case ACK_FREQUENCY_FRAME:
frames.push_back(QuicFrame(new QuicAckFrequencyFrame()));
break;
default:
ASSERT_TRUE(false)
<< "Please fix CopyQuicFrames if a new frame type is added.";
break;
}
}
QuicFrames copy =
CopyQuicFrames(quiche::SimpleBufferAllocator::Get(), frames);
ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
EXPECT_EQ(i, copy[i].type);
if (i == MESSAGE_FRAME) {
// Verify message frame is correctly copied.
EXPECT_EQ(1u, copy[i].message_frame->message_id);
EXPECT_EQ(nullptr, copy[i].message_frame->data);
EXPECT_EQ(7u, copy[i].message_frame->message_length);
ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
frames[i].message_frame->message_data[0].data(), 7));
} else if (i == PATH_CHALLENGE_FRAME) {
EXPECT_EQ(copy[i].path_challenge_frame.control_frame_id,
frames[i].path_challenge_frame.control_frame_id);
EXPECT_EQ(memcmp(&copy[i].path_challenge_frame.data_buffer,
&frames[i].path_challenge_frame.data_buffer,
copy[i].path_challenge_frame.data_buffer.size()),
0);
} else if (i == PATH_RESPONSE_FRAME) {
EXPECT_EQ(copy[i].path_response_frame.control_frame_id,
frames[i].path_response_frame.control_frame_id);
EXPECT_EQ(memcmp(&copy[i].path_response_frame.data_buffer,
&frames[i].path_response_frame.data_buffer,
copy[i].path_response_frame.data_buffer.size()),
0);
}
}
DeleteFrames(&frames);
DeleteFrames(&copy);
}
class PacketNumberQueueTest : public QuicTest {};
// Tests that a queue contains the expected data after calls to Add().
TEST_F(PacketNumberQueueTest, AddRange) {
PacketNumberQueue queue;
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
queue.Add(QuicPacketNumber(53));
EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
for (int i = 1; i < 51; ++i) {
EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
}
EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
EXPECT_EQ(51u, queue.NumPacketsSlow());
EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
queue.Add(QuicPacketNumber(70));
EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
}
// Tests Contains function
TEST_F(PacketNumberQueueTest, Contains) {
PacketNumberQueue queue;
EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
queue.Add(QuicPacketNumber(20));
for (int i = 1; i < 5; ++i) {
EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
}
for (int i = 5; i < 10; ++i) {
EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
}
for (int i = 10; i < 20; ++i) {
EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
}
EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
PacketNumberQueue queue2;
EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
for (int i = 1; i < 51; ++i) {
queue2.Add(QuicPacketNumber(2 * i));
}
EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
for (int i = 1; i < 51; ++i) {
if (i % 2 == 0) {
EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
} else {
EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
}
}
EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
}
// Tests that a queue contains the expected data after calls to RemoveUpTo().
TEST_F(PacketNumberQueueTest, Removal) {
PacketNumberQueue queue;
EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
for (int i = 1; i < 51; ++i) {
EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
}
for (int i = 51; i < 100; ++i) {
EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
}
EXPECT_EQ(49u, queue.NumPacketsSlow());
EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
PacketNumberQueue queue2;
queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
EXPECT_TRUE(queue2.Empty());
}
// Tests that a queue is empty when all of its elements are removed.
TEST_F(PacketNumberQueueTest, Empty) {
PacketNumberQueue queue;
EXPECT_TRUE(queue.Empty());
EXPECT_EQ(0u, queue.NumPacketsSlow());
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
EXPECT_TRUE(queue.Empty());
EXPECT_EQ(0u, queue.NumPacketsSlow());
}
// Tests that logging the state of a PacketNumberQueue does not crash.
TEST_F(PacketNumberQueueTest, LogDoesNotCrash) {
std::ostringstream oss;
PacketNumberQueue queue;
oss << queue;
queue.Add(QuicPacketNumber(1));
queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
oss << queue;
}
// Tests that the iterators returned from a packet queue iterate over the queue.
TEST_F(PacketNumberQueueTest, Iterators) {
PacketNumberQueue queue;
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
queue.begin(), queue.end());
PacketNumberQueue queue2;
for (int i = 1; i < 100; i++) {
queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
}
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
queue2.begin(), queue2.end());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(1), QuicPacketNumber(100)));
EXPECT_EQ(expected_intervals, actual_intervals);
EXPECT_EQ(expected_intervals, actual_intervals2);
EXPECT_EQ(actual_intervals, actual_intervals2);
}
TEST_F(PacketNumberQueueTest, ReversedIterators) {
PacketNumberQueue queue;
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
PacketNumberQueue queue2;
for (int i = 1; i < 100; i++) {
queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
}
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
queue.rbegin(), queue.rend());
const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
queue2.rbegin(), queue2.rend());
std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
QuicPacketNumber(1), QuicPacketNumber(100)));
EXPECT_EQ(expected_intervals, actual_intervals);
EXPECT_EQ(expected_intervals, actual_intervals2);
EXPECT_EQ(actual_intervals, actual_intervals2);
PacketNumberQueue queue3;
for (int i = 1; i < 20; i++) {
queue3.Add(QuicPacketNumber(2 * i));
}
auto begin = queue3.begin();
auto end = queue3.end();
--end;
auto rbegin = queue3.rbegin();
auto rend = queue3.rend();
--rend;
EXPECT_EQ(*begin, *rend);
EXPECT_EQ(*rbegin, *end);
}
TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
PacketNumberQueue queue;
queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
EXPECT_EQ(3u, queue.NumIntervals());
EXPECT_EQ(10u, queue.LastIntervalLength());
EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
EXPECT_EQ(2u, queue.NumIntervals());
EXPECT_EQ(10u, queue.LastIntervalLength());
EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
}
} // namespace
} // namespace test
} // namespace quic