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