1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/src/quic/core/congestion_control/general_loss_algorithm.h"
6 
7 #include <algorithm>
8 #include <cstdint>
9 
10 #include "net/third_party/quiche/src/quic/core/congestion_control/rtt_stats.h"
11 #include "net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h"
12 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
13 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
14 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
15 #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
16 
17 namespace quic {
18 namespace test {
19 namespace {
20 
21 // Default packet length.
22 const uint32_t kDefaultLength = 1000;
23 
24 class GeneralLossAlgorithmTest : public QuicTest {
25  protected:
GeneralLossAlgorithmTest()26   GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
27     rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
28                          QuicTime::Delta::Zero(), clock_.Now());
29     EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
30     loss_algorithm_.SetPacketNumberSpace(HANDSHAKE_DATA);
31   }
32 
~GeneralLossAlgorithmTest()33   ~GeneralLossAlgorithmTest() override {}
34 
SendDataPacket(uint64_t packet_number,QuicPacketLength encrypted_length)35   void SendDataPacket(uint64_t packet_number,
36                       QuicPacketLength encrypted_length) {
37     QuicStreamFrame frame;
38     frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
39         CurrentSupportedVersions()[0].transport_version,
40         Perspective::IS_CLIENT);
41     SerializedPacket packet(QuicPacketNumber(packet_number),
42                             PACKET_1BYTE_PACKET_NUMBER, nullptr,
43                             encrypted_length, false, false);
44     packet.retransmittable_frames.push_back(QuicFrame(frame));
45     unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
46                                    true);
47   }
48 
SendDataPacket(uint64_t packet_number)49   void SendDataPacket(uint64_t packet_number) {
50     SendDataPacket(packet_number, kDefaultLength);
51   }
52 
SendAckPacket(uint64_t packet_number)53   void SendAckPacket(uint64_t packet_number) {
54     SerializedPacket packet(QuicPacketNumber(packet_number),
55                             PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
56                             true, false);
57     unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
58                                    false);
59   }
60 
VerifyLosses(uint64_t largest_newly_acked,const AckedPacketVector & packets_acked,const std::vector<uint64_t> & losses_expected)61   void VerifyLosses(uint64_t largest_newly_acked,
62                     const AckedPacketVector& packets_acked,
63                     const std::vector<uint64_t>& losses_expected) {
64     unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
65         APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
66     LostPacketVector lost_packets;
67     loss_algorithm_.DetectLosses(unacked_packets_, clock_.Now(), rtt_stats_,
68                                  QuicPacketNumber(largest_newly_acked),
69                                  packets_acked, &lost_packets);
70     ASSERT_EQ(losses_expected.size(), lost_packets.size());
71     for (size_t i = 0; i < losses_expected.size(); ++i) {
72       EXPECT_EQ(lost_packets[i].packet_number,
73                 QuicPacketNumber(losses_expected[i]));
74     }
75   }
76 
77   QuicUnackedPacketMap unacked_packets_;
78   GeneralLossAlgorithm loss_algorithm_;
79   RttStats rtt_stats_;
80   MockClock clock_;
81 };
82 
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1Packet)83 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
84   const size_t kNumSentPackets = 5;
85   // Transmit 5 packets.
86   for (size_t i = 1; i <= kNumSentPackets; ++i) {
87     SendDataPacket(i);
88   }
89   AckedPacketVector packets_acked;
90   // No loss on one ack.
91   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
92   packets_acked.push_back(AckedPacket(
93       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
94   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
95   packets_acked.clear();
96   // No loss on two acks.
97   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
98   packets_acked.push_back(AckedPacket(
99       QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
100   VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
101   packets_acked.clear();
102   // Loss on three acks.
103   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
104   packets_acked.push_back(AckedPacket(
105       QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
106   VerifyLosses(4, packets_acked, {1});
107   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
108 }
109 
110 // A stretch ack is an ack that covers more than 1 packet of previously
111 // unacknowledged data.
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1PacketWith1StretchAck)112 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
113   const size_t kNumSentPackets = 10;
114   // Transmit 10 packets.
115   for (size_t i = 1; i <= kNumSentPackets; ++i) {
116     SendDataPacket(i);
117   }
118   AckedPacketVector packets_acked;
119   // Nack the first packet 3 times in a single StretchAck.
120   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
121   packets_acked.push_back(AckedPacket(
122       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
123   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
124   packets_acked.push_back(AckedPacket(
125       QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
126   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
127   packets_acked.push_back(AckedPacket(
128       QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
129   VerifyLosses(4, packets_acked, {1});
130   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
131 }
132 
133 // Ack a packet 3 packets ahead, causing a retransmit.
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1PacketSingleAck)134 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
135   const size_t kNumSentPackets = 10;
136   // Transmit 10 packets.
137   for (size_t i = 1; i <= kNumSentPackets; ++i) {
138     SendDataPacket(i);
139   }
140   AckedPacketVector packets_acked;
141   // Nack the first packet 3 times in an AckFrame with three missing packets.
142   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
143   packets_acked.push_back(AckedPacket(
144       QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
145   VerifyLosses(4, packets_acked, {1});
146   EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
147             loss_algorithm_.GetLossTimeout());
148 }
149 
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmit1Packet)150 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
151   const size_t kNumSentPackets = 2;
152   // Transmit 2 packets.
153   for (size_t i = 1; i <= kNumSentPackets; ++i) {
154     SendDataPacket(i);
155   }
156   AckedPacketVector packets_acked;
157   // Early retransmit when the final packet gets acked and the first is nacked.
158   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
159   packets_acked.push_back(AckedPacket(
160       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
161   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
162   packets_acked.clear();
163   EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
164             loss_algorithm_.GetLossTimeout());
165 
166   clock_.AdvanceTime(1.25 * rtt_stats_.latest_rtt());
167   VerifyLosses(2, packets_acked, {1});
168   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
169 }
170 
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmitAllPackets)171 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
172   const size_t kNumSentPackets = 5;
173   for (size_t i = 1; i <= kNumSentPackets; ++i) {
174     SendDataPacket(i);
175     // Advance the time 1/4 RTT between 3 and 4.
176     if (i == 3) {
177       clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
178     }
179   }
180   AckedPacketVector packets_acked;
181   // Early retransmit when the final packet gets acked and 1.25 RTTs have
182   // elapsed since the packets were sent.
183   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
184   packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
185                                       kMaxOutgoingPacketSize,
186                                       QuicTime::Zero()));
187   // This simulates a single ack following multiple missing packets with FACK.
188   VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
189   packets_acked.clear();
190   // The time has already advanced 1/4 an RTT, so ensure the timeout is set
191   // 1.25 RTTs after the earliest pending packet(3), not the last(4).
192   EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
193             loss_algorithm_.GetLossTimeout());
194 
195   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
196   VerifyLosses(kNumSentPackets, packets_acked, {3});
197   EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
198             loss_algorithm_.GetLossTimeout());
199   clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
200   VerifyLosses(kNumSentPackets, packets_acked, {4});
201   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
202 }
203 
TEST_F(GeneralLossAlgorithmTest,DontEarlyRetransmitNeuteredPacket)204 TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
205   const size_t kNumSentPackets = 2;
206   // Transmit 2 packets.
207   for (size_t i = 1; i <= kNumSentPackets; ++i) {
208     SendDataPacket(i);
209   }
210   AckedPacketVector packets_acked;
211   // Neuter packet 1.
212   unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
213   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
214 
215   // Early retransmit when the final packet gets acked and the first is nacked.
216   unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
217       APPLICATION_DATA, QuicPacketNumber(2));
218   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
219   packets_acked.push_back(AckedPacket(
220       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
221   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
222   EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
223             loss_algorithm_.GetLossTimeout());
224 }
225 
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmitWithLargerUnackablePackets)226 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
227   // Transmit 2 data packets and one ack.
228   SendDataPacket(1);
229   SendDataPacket(2);
230   SendAckPacket(3);
231   AckedPacketVector packets_acked;
232   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
233 
234   // Early retransmit when the final packet gets acked and the first is nacked.
235   unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
236       APPLICATION_DATA, QuicPacketNumber(2));
237   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
238   packets_acked.push_back(AckedPacket(
239       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
240   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
241   packets_acked.clear();
242   EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
243             loss_algorithm_.GetLossTimeout());
244 
245   // The packet should be lost once the loss timeout is reached.
246   clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
247   VerifyLosses(2, packets_acked, {1});
248   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
249 }
250 
TEST_F(GeneralLossAlgorithmTest,AlwaysLosePacketSent1RTTEarlier)251 TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
252   // Transmit 1 packet and then wait an rtt plus 1ms.
253   SendDataPacket(1);
254   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
255                      QuicTime::Delta::FromMilliseconds(1));
256 
257   // Transmit 2 packets.
258   SendDataPacket(2);
259   SendDataPacket(3);
260   AckedPacketVector packets_acked;
261   // Wait another RTT and ack 2.
262   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
263   unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
264       APPLICATION_DATA, QuicPacketNumber(2));
265   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
266   packets_acked.push_back(AckedPacket(
267       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
268   VerifyLosses(2, packets_acked, {1});
269 }
270 
TEST_F(GeneralLossAlgorithmTest,IncreaseTimeThresholdUponSpuriousLoss)271 TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
272   loss_algorithm_.enable_adaptive_time_threshold();
273   loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
274   EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
275   EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
276   const size_t kNumSentPackets = 10;
277   // Transmit 2 packets at 1/10th an RTT interval.
278   for (size_t i = 1; i <= kNumSentPackets; ++i) {
279     SendDataPacket(i);
280     clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
281   }
282   EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
283   AckedPacketVector packets_acked;
284   // Expect the timer to not be set.
285   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
286   // Packet 1 should not be lost until 1/4 RTTs pass.
287   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
288   packets_acked.push_back(AckedPacket(
289       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
290   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
291   packets_acked.clear();
292   // Expect the timer to be set to 1/4 RTT's in the future.
293   EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
294             loss_algorithm_.GetLossTimeout() - clock_.Now());
295   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
296   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
297   VerifyLosses(2, packets_acked, {1});
298   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
299   // Retransmit packet 1 as 11 and 2 as 12.
300   SendDataPacket(11);
301   SendDataPacket(12);
302 
303   // Advance the time 1/4 RTT and indicate the loss was spurious.
304   // The new threshold should be 1/2 RTT.
305   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
306   loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
307                                        clock_.Now(), QuicPacketNumber(1),
308                                        QuicPacketNumber(2));
309   EXPECT_EQ(1, loss_algorithm_.reordering_shift());
310 }
311 
TEST_F(GeneralLossAlgorithmTest,IncreaseReorderingThresholdUponSpuriousLoss)312 TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
313   loss_algorithm_.set_use_adaptive_reordering_threshold(true);
314   for (size_t i = 1; i <= 4; ++i) {
315     SendDataPacket(i);
316   }
317   // Acking 4 causes 1 detected lost.
318   AckedPacketVector packets_acked;
319   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
320   packets_acked.push_back(AckedPacket(
321       QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
322   VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
323   packets_acked.clear();
324 
325   // Retransmit 1 as 5.
326   SendDataPacket(5);
327 
328   // Acking 1 such that it was detected lost spuriously.
329   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
330   packets_acked.push_back(AckedPacket(
331       QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
332   loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
333                                        clock_.Now(), QuicPacketNumber(1),
334                                        QuicPacketNumber(4));
335   VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
336   packets_acked.clear();
337 
338   // Verify acking 5 does not cause 2 detected lost.
339   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
340   packets_acked.push_back(AckedPacket(
341       QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
342   VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
343   packets_acked.clear();
344 
345   SendDataPacket(6);
346 
347   // Acking 6 will causes 2 detected lost.
348   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
349   packets_acked.push_back(AckedPacket(
350       QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
351   VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
352   packets_acked.clear();
353 
354   // Retransmit 2 as 7.
355   SendDataPacket(7);
356 
357   // Acking 2 such that it was detected lost spuriously.
358   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
359   packets_acked.push_back(AckedPacket(
360       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
361   loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
362                                        clock_.Now(), QuicPacketNumber(2),
363                                        QuicPacketNumber(6));
364   VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
365   packets_acked.clear();
366 
367   // Acking 7 will not cause 3 as detected lost.
368   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
369   packets_acked.push_back(AckedPacket(
370       QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
371   VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
372   packets_acked.clear();
373 }
374 
TEST_F(GeneralLossAlgorithmTest,DefaultIetfLossDetection)375 TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
376   loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
377   for (size_t i = 1; i <= 6; ++i) {
378     SendDataPacket(i);
379   }
380   // Packet threshold loss detection.
381   AckedPacketVector packets_acked;
382   // No loss on one ack.
383   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
384   packets_acked.push_back(AckedPacket(
385       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
386   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
387   packets_acked.clear();
388   // No loss on two acks.
389   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
390   packets_acked.push_back(AckedPacket(
391       QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
392   VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
393   packets_acked.clear();
394   // Loss on three acks.
395   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
396   packets_acked.push_back(AckedPacket(
397       QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
398   VerifyLosses(4, packets_acked, {1});
399   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
400   packets_acked.clear();
401 
402   SendDataPacket(7);
403 
404   // Time threshold loss detection.
405   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
406   packets_acked.push_back(AckedPacket(
407       QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
408   VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
409   packets_acked.clear();
410   EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
411                 (rtt_stats_.smoothed_rtt() >> 3),
412             loss_algorithm_.GetLossTimeout());
413   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
414                      (rtt_stats_.smoothed_rtt() >> 3));
415   VerifyLosses(6, packets_acked, {5});
416   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
417 }
418 
TEST_F(GeneralLossAlgorithmTest,IetfLossDetectionWithOneFourthRttDelay)419 TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
420   loss_algorithm_.set_reordering_shift(2);
421   SendDataPacket(1);
422   SendDataPacket(2);
423 
424   AckedPacketVector packets_acked;
425   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
426   packets_acked.push_back(AckedPacket(
427       QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
428   VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
429   packets_acked.clear();
430   EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
431                 (rtt_stats_.smoothed_rtt() >> 2),
432             loss_algorithm_.GetLossTimeout());
433   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
434                      (rtt_stats_.smoothed_rtt() >> 2));
435   VerifyLosses(2, packets_acked, {1});
436   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
437 }
438 
TEST_F(GeneralLossAlgorithmTest,NoPacketThresholdForRuntPackets)439 TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
440   loss_algorithm_.disable_packet_threshold_for_runt_packets();
441   for (size_t i = 1; i <= 6; ++i) {
442     SendDataPacket(i);
443   }
444   // Send a small packet.
445   SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
446   // No packet threshold for runt packet.
447   AckedPacketVector packets_acked;
448   unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
449   packets_acked.push_back(AckedPacket(
450       QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
451   // Verify no packet is detected lost because packet 7 is a runt.
452   VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
453   EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
454                 (rtt_stats_.smoothed_rtt() >> 2),
455             loss_algorithm_.GetLossTimeout());
456   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
457                      (rtt_stats_.smoothed_rtt() >> 2));
458   // Verify packets are declared lost because time threshold has passed.
459   VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
460   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
461 }
462 
463 }  // namespace
464 }  // namespace test
465 }  // namespace quic
466