| // 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(©[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(©[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(©); |
| } |
| |
| 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 |