blob: 9cbc6e7c26ba9a08a48fb271019237f5894fd8be [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quiche/src/quic/core/quic_received_packet_manager.h"
#include <algorithm>
#include <ostream>
#include <vector>
#include "net/third_party/quiche/src/quic/core/quic_connection_stats.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
namespace quic {
namespace test {
namespace {
struct TestParams {
explicit TestParams(QuicTransportVersion version) : version(version) {}
friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
os << "{ version: " << QuicVersionToString(p.version) << " }";
return os;
}
QuicTransportVersion version;
};
std::vector<TestParams> GetTestParams() {
std::vector<TestParams> params;
QuicTransportVersionVector all_supported_versions =
AllSupportedTransportVersions();
for (size_t i = 0; i < all_supported_versions.size(); ++i) {
params.push_back(TestParams(all_supported_versions[i]));
}
return params;
}
class QuicReceivedPacketManagerTest : public QuicTestWithParam<TestParams> {
protected:
QuicReceivedPacketManagerTest() : received_manager_(&stats_) {
received_manager_.set_save_timestamps(true);
}
void RecordPacketReceipt(uint64_t packet_number) {
RecordPacketReceipt(packet_number, QuicTime::Zero());
}
void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
QuicPacketHeader header;
header.packet_number = QuicPacketNumber(packet_number);
received_manager_.RecordPacketReceived(header, receipt_time);
}
QuicConnectionStats stats_;
QuicReceivedPacketManager received_manager_;
};
INSTANTIATE_TEST_SUITE_P(QuicReceivedPacketManagerTest,
QuicReceivedPacketManagerTest,
::testing::ValuesIn(GetTestParams()));
TEST_P(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
QuicPacketHeader header;
header.packet_number = QuicPacketNumber(2u);
received_manager_.RecordPacketReceived(header, QuicTime::Zero());
header.packet_number = QuicPacketNumber(7u);
received_manager_.RecordPacketReceived(header, QuicTime::Zero());
EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
}
TEST_P(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
QuicPacketHeader header;
header.packet_number = QuicPacketNumber(2u);
QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
EXPECT_FALSE(received_manager_.ack_frame_updated());
received_manager_.RecordPacketReceived(header, two_ms);
EXPECT_TRUE(received_manager_.ack_frame_updated());
QuicFrame ack = received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
EXPECT_FALSE(received_manager_.ack_frame_updated());
// When UpdateReceivedPacketInfo with a time earlier than the time of the
// largest observed packet, make sure that the delta is 0, not negative.
EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_frame->ack_delay_time);
EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
QuicTime four_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(4);
ack = received_manager_.GetUpdatedAckFrame(four_ms);
EXPECT_FALSE(received_manager_.ack_frame_updated());
// When UpdateReceivedPacketInfo after not having received a new packet,
// the delta should still be accurate.
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
ack.ack_frame->ack_delay_time);
// And received packet times won't have change.
EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
header.packet_number = QuicPacketNumber(999u);
received_manager_.RecordPacketReceived(header, two_ms);
header.packet_number = QuicPacketNumber(4u);
received_manager_.RecordPacketReceived(header, two_ms);
header.packet_number = QuicPacketNumber(1000u);
received_manager_.RecordPacketReceived(header, two_ms);
EXPECT_TRUE(received_manager_.ack_frame_updated());
ack = received_manager_.GetUpdatedAckFrame(two_ms);
EXPECT_FALSE(received_manager_.ack_frame_updated());
// UpdateReceivedPacketInfo should discard any times which can't be
// expressed on the wire.
EXPECT_EQ(2u, ack.ack_frame->received_packet_times.size());
}
TEST_P(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) {
EXPECT_FALSE(received_manager_.ack_frame_updated());
RecordPacketReceipt(1);
EXPECT_TRUE(received_manager_.ack_frame_updated());
RecordPacketReceipt(6);
RecordPacketReceipt(2,
QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
EXPECT_EQ(4u, stats_.max_sequence_reordering);
EXPECT_EQ(1000, stats_.max_time_reordering_us);
EXPECT_EQ(1u, stats_.packets_reordered);
}
TEST_P(QuicReceivedPacketManagerTest, LimitAckRanges) {
received_manager_.set_max_ack_ranges(10);
EXPECT_FALSE(received_manager_.ack_frame_updated());
for (int i = 0; i < 100; ++i) {
RecordPacketReceipt(1 + 2 * i);
EXPECT_TRUE(received_manager_.ack_frame_updated());
received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
received_manager_.ack_frame().packets.Max());
for (int j = 0; j < std::min(10, i + 1); ++j) {
ASSERT_GE(i, j);
EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
QuicPacketNumber(1 + (i - j) * 2)));
if (i > j) {
EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
QuicPacketNumber((i - j) * 2)));
}
}
}
}
TEST_P(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) {
EXPECT_FALSE(received_manager_.ack_frame_updated());
RecordPacketReceipt(1, QuicTime::Zero());
EXPECT_TRUE(received_manager_.ack_frame_updated());
EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size());
RecordPacketReceipt(2,
QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1));
EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
RecordPacketReceipt(3, QuicTime::Zero());
EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size());
}
TEST_P(QuicReceivedPacketManagerTest, HasMissingPackets) {
if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
EXPECT_QUIC_BUG(received_manager_.PeerFirstSendingPacketNumber(),
"No packets have been received yet");
} else {
EXPECT_EQ(QuicPacketNumber(1),
received_manager_.PeerFirstSendingPacketNumber());
}
RecordPacketReceipt(4, QuicTime::Zero());
if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
EXPECT_EQ(QuicPacketNumber(4),
received_manager_.PeerFirstSendingPacketNumber());
EXPECT_FALSE(received_manager_.HasMissingPackets());
} else {
EXPECT_TRUE(received_manager_.HasMissingPackets());
EXPECT_EQ(QuicPacketNumber(1),
received_manager_.PeerFirstSendingPacketNumber());
}
RecordPacketReceipt(3, QuicTime::Zero());
if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
EXPECT_FALSE(received_manager_.HasMissingPackets());
EXPECT_EQ(QuicPacketNumber(3),
received_manager_.PeerFirstSendingPacketNumber());
} else {
EXPECT_TRUE(received_manager_.HasMissingPackets());
EXPECT_EQ(QuicPacketNumber(1),
received_manager_.PeerFirstSendingPacketNumber());
}
RecordPacketReceipt(1, QuicTime::Zero());
EXPECT_EQ(QuicPacketNumber(1),
received_manager_.PeerFirstSendingPacketNumber());
EXPECT_TRUE(received_manager_.HasMissingPackets());
RecordPacketReceipt(2, QuicTime::Zero());
EXPECT_EQ(QuicPacketNumber(1),
received_manager_.PeerFirstSendingPacketNumber());
EXPECT_FALSE(received_manager_.HasMissingPackets());
}
} // namespace
} // namespace test
} // namespace quic