#include "net/quic/quic_sent_packet_manager.h"
#include "base/stl_util.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/test_tools/quic_config_peer.h"
#include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
using std::vector;
+using testing::AnyNumber;
using testing::ElementsAre;
using testing::Pair;
using testing::Pointwise;
class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
protected:
QuicSentPacketManagerTest()
- : manager_(true, &clock_, &stats_, kFixRate, kNack),
- send_algorithm_(new StrictMock<MockSendAlgorithm>) {
+ : manager_(true, &clock_, &stats_, kCubic, kNack),
+ send_algorithm_(new StrictMock<MockSendAlgorithm>),
+ network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
// Disable tail loss probes for most tests.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
// Advance the time 1s so the send times are never QuicTime::Zero.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+ manager_.set_network_change_visitor(network_change_visitor_.get());
}
virtual ~QuicSentPacketManagerTest() OVERRIDE {
void ExpectAck(QuicPacketSequenceNumber largest_observed) {
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
true, _, ElementsAre(Pair(largest_observed, _)), _));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
}
void ExpectUpdatedRtt(QuicPacketSequenceNumber largest_observed) {
EXPECT_CALL(*send_algorithm_,
OnCongestionEvent(true, _, _, _));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
}
void ExpectAckAndLoss(bool rtt_updated,
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
rtt_updated, _, ElementsAre(Pair(largest_observed, _)),
ElementsAre(Pair(lost_packet, _))));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
}
// |packets_acked| and |packets_lost| should be in sequence number order.
OnCongestionEvent(rtt_updated, _,
Pointwise(KeyEq(), ack_vector),
Pointwise(KeyEq(), lost_vector)));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillRepeatedly(Return(100 * kDefaultTCPMSS));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_)).
+ Times(AnyNumber());
}
// Retransmits a packet as though it was a TLP retransmission, because TLP
MockClock clock_;
QuicConnectionStats stats_;
MockSendAlgorithm* send_algorithm_;
+ scoped_ptr<MockNetworkChangeVisitor> network_change_visitor_;
};
TEST_F(QuicSentPacketManagerTest, IsUnacked) {
RetransmitAndSendPacket(1, 2);
// Ack 2 but not 1.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.missing_packets.insert(1);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.missing_packets.insert(1);
ExpectAck(2);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
// Packet 1 is unacked, pending, but not retransmittable.
QuicPacketSequenceNumber unacked[] = { 1 };
EXPECT_TRUE(manager_.HasPendingRetransmissions());
// Ack 1.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
ExpectAck(1);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
// There should no longer be a pending retransmission.
EXPECT_FALSE(manager_.HasPendingRetransmissions());
// Ack 1 but not 2.
ExpectAck(1);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
// 2 should be unacked, since it may provide an RTT measurement.
QuicPacketSequenceNumber unacked[] = { 2 };
// Ack 1 but not 2.
ExpectAck(1);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
// 2 remains unacked, but no packets have retransmittable data.
QuicPacketSequenceNumber unacked[] = { 2 };
// First, ACK packet 1 which makes packet 2 non-retransmittable.
ExpectAck(1);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
SendDataPacket(3);
SendDataPacket(4);
clock_.AdvanceTime(rtt);
// Next, NACK packet 2 three times.
- received_info.largest_observed = 3;
- received_info.missing_packets.insert(2);
+ ack_frame.largest_observed = 3;
+ ack_frame.missing_packets.insert(2);
ExpectAck(3);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
- received_info.largest_observed = 4;
+ ack_frame.largest_observed = 4;
ExpectAck(4);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
- received_info.largest_observed = 5;
+ ack_frame.largest_observed = 5;
ExpectAckAndLoss(true, 5, 2);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
// No packets remain unacked.
VerifyUnackedPackets(NULL, 0);
// Fire the RTO, which will mark 2 for retransmission (but will not send it).
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
manager_.OnRetransmissionTimeout();
EXPECT_TRUE(manager_.HasPendingRetransmissions());
// Ack 1 but not 2, before 2 is able to be sent.
// Since 1 has been retransmitted, it has already been lost, and so the
// send algorithm is not informed that it has been ACK'd.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
ExpectUpdatedRtt(1);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
// Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
QuicPacketSequenceNumber unacked[] = { 2 };
// Ack 1 but not 2 or 3.
ExpectAck(1);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 1;
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 1;
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
// 2 and 3 remain unacked, but no packets have retransmittable data.
QuicPacketSequenceNumber unacked[] = { 2, 3 };
// Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
SendDataPacket(4);
- received_info.largest_observed = 4;
- received_info.missing_packets.insert(2);
+ ack_frame.largest_observed = 4;
+ ack_frame.missing_packets.insert(2);
QuicPacketSequenceNumber acked[] = { 3, 4 };
ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
QuicPacketSequenceNumber unacked2[] = { 2 };
VerifyUnackedPackets(unacked2, arraysize(unacked2));
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
SendDataPacket(5);
- received_info.largest_observed = 5;
+ ack_frame.largest_observed = 5;
ExpectAckAndLoss(true, 5, 2);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
VerifyUnackedPackets(NULL, 0);
EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
SendDataPacket(4);
// Ack 2 and 3, and mark 1 as revived.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 3;
- received_info.missing_packets.insert(1);
- received_info.revived_packets.insert(1);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 3;
+ ack_frame.missing_packets.insert(1);
+ ack_frame.revived_packets.insert(1);
QuicPacketSequenceNumber acked[] = { 2, 3 };
ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(manager_.HasPendingRetransmissions());
QuicPacketSequenceNumber unacked[] = { 1, 4 };
VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
// Ack the 4th packet and expect the 1st to be considered lost.
- received_info.largest_observed = 4;
+ ack_frame.largest_observed = 4;
ExpectAckAndLoss(true, 4, 1);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(manager_.HasPendingRetransmissions());
VerifyRetransmittablePackets(NULL, 0);
SendFecPacket(5);
// Ack 2, 3, and 4, and expect the 1st to be considered lost.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 4;
- received_info.missing_packets.insert(1);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 4;
+ ack_frame.missing_packets.insert(1);
QuicPacketSequenceNumber acked[] = { 2, 3, 4 };
QuicPacketSequenceNumber lost[] = { 1 };
ExpectAcksAndLosses(true, acked, arraysize(acked), lost, arraysize(lost));
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_TRUE(manager_.HasPendingRetransmissions());
QuicPacketSequenceNumber unacked[] = { 1, 5 };
// Ack 5th packet (FEC) and revive 1st packet. 1st packet should now be
// removed from pending retransmissions map.
- received_info.largest_observed = 5;
- received_info.revived_packets.insert(1);
+ ack_frame.largest_observed = 5;
+ ack_frame.revived_packets.insert(1);
ExpectAck(5);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(manager_.HasPendingRetransmissions());
VerifyRetransmittablePackets(NULL, 0);
RetransmitAndSendPacket(4, 5);
// Truncated ack with 4 NACKs, so the first packet is lost.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 4;
- received_info.missing_packets.insert(1);
- received_info.missing_packets.insert(2);
- received_info.missing_packets.insert(3);
- received_info.missing_packets.insert(4);
- received_info.is_truncated = true;
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 4;
+ ack_frame.missing_packets.insert(1);
+ ack_frame.missing_packets.insert(2);
+ ack_frame.missing_packets.insert(3);
+ ack_frame.missing_packets.insert(4);
+ ack_frame.is_truncated = true;
QuicPacketSequenceNumber lost[] = { 1 };
ExpectAcksAndLosses(true, NULL, 0, lost, arraysize(lost));
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
// High water mark will be raised.
QuicPacketSequenceNumber unacked[] = { 2, 3, 4, 5 };
// Ack previous transmission
{
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.missing_packets.insert(1);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.missing_packets.insert(1);
ExpectAck(2);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_TRUE(manager_.IsUnacked(4));
}
// Truncated ack with 4 NACKs
{
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 6;
- received_info.missing_packets.insert(3);
- received_info.missing_packets.insert(4);
- received_info.missing_packets.insert(5);
- received_info.missing_packets.insert(6);
- received_info.is_truncated = true;
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 6;
+ ack_frame.missing_packets.insert(3);
+ ack_frame.missing_packets.insert(4);
+ ack_frame.missing_packets.insert(5);
+ ack_frame.missing_packets.insert(6);
+ ack_frame.is_truncated = true;
ExpectAckAndLoss(false, 1, 3);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
}
// High water mark will be raised.
VerifyRetransmittablePackets(NULL, 0);
// Ack 2, which has never been sent, so there's no rtt update.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- manager_.OnIncomingAck(received_info, clock_.Now());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(3u, manager_.GetLeastUnackedSentPacket());
}
SendAckPacket(2);
// Now ack the ack and expect an RTT update.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.delta_time_largest_observed =
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.delta_time_largest_observed =
QuicTime::Delta::FromMilliseconds(5);
ExpectAck(1);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
SendAckPacket(3);
// Now ack the ack and expect only an RTT update.
- received_info.largest_observed = 3;
+ ack_frame.largest_observed = 3;
ExpectUpdatedRtt(3);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
}
TEST_F(QuicSentPacketManagerTest, Rtt) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
ExpectAck(sequence_number);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = sequence_number;
- received_info.delta_time_largest_observed =
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = sequence_number;
+ ack_frame.delta_time_largest_observed =
QuicTime::Delta::FromMilliseconds(5);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
}
clock_.AdvanceTime(expected_rtt);
ExpectAck(sequence_number);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = sequence_number;
- received_info.delta_time_largest_observed =
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = sequence_number;
+ ack_frame.delta_time_largest_observed =
QuicTime::Delta::FromMilliseconds(11);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
}
clock_.AdvanceTime(expected_rtt);
ExpectAck(sequence_number);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = sequence_number;
- received_info.delta_time_largest_observed = QuicTime::Delta::Infinite();
- manager_.OnIncomingAck(received_info, clock_.Now());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = sequence_number;
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Infinite();
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
}
clock_.AdvanceTime(expected_rtt);
ExpectAck(sequence_number);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = sequence_number;
- received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
- manager_.OnIncomingAck(received_info, clock_.Now());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = sequence_number;
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(expected_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->latest_rtt());
}
// Ack the third and ensure the first two are still pending.
ExpectAck(3);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 3;
- received_info.missing_packets.insert(1);
- received_info.missing_packets.insert(2);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 3;
+ ack_frame.missing_packets.insert(1);
+ ack_frame.missing_packets.insert(2);
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
// Acking two more packets will lose both of them due to nacks.
- received_info.largest_observed = 5;
+ ack_frame.largest_observed = 5;
QuicPacketSequenceNumber lost[] = { 1, 2 };
ExpectAcksAndLosses(false, NULL, 0, lost, arraysize(lost));
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(manager_.HasPendingRetransmissions());
EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
// The final RTO abandons all of them.
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
manager_.OnRetransmissionTimeout();
EXPECT_TRUE(manager_.HasPendingRetransmissions());
EXPECT_EQ(2u, stats_.tlp_count);
// and ensure the first four crypto packets get abandoned, but not lost.
QuicPacketSequenceNumber acked[] = { 3, 4, 5, 8, 9 };
ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 9;
- received_info.missing_packets.insert(1);
- received_info.missing_packets.insert(2);
- received_info.missing_packets.insert(6);
- received_info.missing_packets.insert(7);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 9;
+ ack_frame.missing_packets.insert(1);
+ ack_frame.missing_packets.insert(2);
+ ack_frame.missing_packets.insert(6);
+ ack_frame.missing_packets.insert(7);
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
}
// Now ack the second crypto packet, and ensure the first gets removed, but
// the third does not.
ExpectUpdatedRtt(2);
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.missing_packets.insert(1);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.missing_packets.insert(1);
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
QuicPacketSequenceNumber unacked[] = { 3 };
EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
// Ensure both packets get discarded when packet 2 is acked.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 3;
- received_info.missing_packets.insert(1);
- received_info.missing_packets.insert(2);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 3;
+ ack_frame.missing_packets.insert(1);
+ ack_frame.missing_packets.insert(2);
ExpectUpdatedRtt(3);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
VerifyUnackedPackets(NULL, 0);
VerifyRetransmittablePackets(NULL, 0);
}
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
// Ack two packets with 100ms RTT observations.
- ReceivedPacketInfo received_info;
- received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
- received_info.largest_observed = 1;
+ QuicAckFrame ack_frame;
+ ack_frame.delta_time_largest_observed = QuicTime::Delta::Zero();
+ ack_frame.largest_observed = 1;
ExpectAck(1);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
// First ack does not change recent min rtt.
EXPECT_EQ(min_rtt,
QuicSentPacketManagerPeer::GetRttStats(
&manager_)->recent_min_rtt());
- received_info.largest_observed = 2;
+ ack_frame.largest_observed = 2;
ExpectAck(2);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
EXPECT_EQ(min_rtt,
QuicSentPacketManagerPeer::GetRttStats(&manager_)->min_rtt());
}
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
manager_.OnRetransmissionTimeout();
}
SendDataPacket(1);
SendDataPacket(2);
+ SendDataPacket(3);
+ SendDataPacket(4);
QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(500);
EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
// Retransmit the packet by invoking the retransmission timeout.
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
clock_.AdvanceTime(expected_rto_delay);
manager_.OnRetransmissionTimeout();
- RetransmitNextPacket(3);
- RetransmitNextPacket(4);
- EXPECT_FALSE(manager_.HasPendingRetransmissions());
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+ RetransmitNextPacket(5);
+ RetransmitNextPacket(6);
+ EXPECT_EQ(2 * kDefaultLength,
+ QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+ EXPECT_TRUE(manager_.HasPendingRetransmissions());
// The delay should double the second time.
expected_time = clock_.Now().Add(expected_rto_delay).Add(expected_rto_delay);
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
// Ack a packet and ensure the RTO goes back to the original value.
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.missing_packets.insert(1);
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.missing_packets.insert(1);
ExpectUpdatedRtt(2);
- manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
+ EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
+ manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_FALSE(manager_.HasPendingRetransmissions());
+ EXPECT_EQ(4 * kDefaultLength,
+ QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
- expected_time = clock_.Now().Add(expected_rto_delay);
+ // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
+ // and the TLP time. In production, there would always be two TLP's first.
+ expected_time = clock_.Now().Add(QuicTime::Delta::FromMilliseconds(200));
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
}
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
delay = delay.Add(delay);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
manager_.OnRetransmissionTimeout();
RetransmitNextPacket(i + 2);
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
delay = delay.Add(delay);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(2 * kDefaultTCPMSS));
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
manager_.OnRetransmissionTimeout();
RetransmitNextPacket(i + 2);
ExpectAck(2);
EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
.WillOnce(Return(SequenceNumberSet()));
- ReceivedPacketInfo received_info;
- received_info.largest_observed = 2;
- received_info.missing_packets.insert(1);
- manager_.OnIncomingAck(received_info, clock_.Now());
+ QuicAckFrame ack_frame;
+ ack_frame.largest_observed = 2;
+ ack_frame.missing_packets.insert(1);
+ manager_.OnIncomingAck(ack_frame, clock_.Now());
QuicTime timeout(clock_.Now().Add(QuicTime::Delta::FromMilliseconds(10)));
EXPECT_CALL(*loss_algorithm, GetLossTimeout())
QuicConfig config;
QuicConfigPeer::SetReceivedLossDetection(&config, kTIME);
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
+ manager_.SetFromConfig(config);
+
+ EXPECT_EQ(kTime,
+ QuicSentPacketManagerPeer::GetLossAlgorithm(
+ &manager_)->GetLossDetectionType());
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiateTimeLossDetectionFromOptions) {
+ EXPECT_EQ(kNack,
+ QuicSentPacketManagerPeer::GetLossAlgorithm(
+ &manager_)->GetLossDetectionType());
+
+ QuicConfig config;
+ QuicTagVector options;
+ options.push_back(kTIME);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
manager_.SetFromConfig(config);
EXPECT_EQ(kTime,
&manager_)->GetLossDetectionType());
}
+TEST_F(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
+ QuicConfig config;
+ QuicTagVector options;
+
+ options.push_back(kRENO);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ manager_.SetFromConfig(config);
+ EXPECT_EQ(kReno, QuicSentPacketManagerPeer::GetCongestionControlAlgorithm(
+ manager_)->GetCongestionControlType());
+
+ // TODO(rtenneti): Enable the following code after BBR code is checked in.
+#if 0
+ options.clear();
+ options.push_back(kTBBR);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ manager_.SetFromConfig(config);
+ EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetCongestionControlAlgorithm(
+ manager_)->GetCongestionControlType());
+#endif
+}
+
+TEST_F(QuicSentPacketManagerTest, NegotiatePacingFromOptions) {
+ ValueRestore<bool> old_flag(&FLAGS_enable_quic_pacing, true);
+ EXPECT_FALSE(manager_.using_pacing());
+
+ QuicConfig config;
+ QuicTagVector options;
+ options.push_back(kPACE);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange(_));
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+ .WillOnce(Return(100 * kDefaultTCPMSS));
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+ manager_.SetFromConfig(config);
+
+ EXPECT_TRUE(manager_.using_pacing());
+}
} // namespace
} // namespace test