1 // Copyright (c) 2012 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.
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/quic/congestion_control/rtt_stats.h"
10 #include "net/quic/congestion_control/tcp_cubic_sender.h"
11 #include "net/quic/congestion_control/tcp_receiver.h"
12 #include "net/quic/quic_utils.h"
13 #include "net/quic/test_tools/mock_clock.h"
14 #include "net/quic/test_tools/quic_config_peer.h"
15 #include "testing/gtest/include/gtest/gtest.h"
22 const uint32 kDefaultWindowTCP
= 10 * kDefaultTCPMSS
;
24 // TODO(ianswett): Remove 10000 once b/10075719 is fixed.
25 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP
= 10000;
27 class TcpCubicSenderPeer
: public TcpCubicSender
{
29 TcpCubicSenderPeer(const QuicClock
* clock
,
31 QuicTcpCongestionWindow max_tcp_congestion_window
)
33 clock
, &rtt_stats_
, reno
, max_tcp_congestion_window
, &stats_
) {
36 QuicTcpCongestionWindow
congestion_window() {
37 return congestion_window_
;
40 QuicTcpCongestionWindow
slowstart_threshold() {
41 return slowstart_threshold_
;
44 const HybridSlowStart
& hybrid_slow_start() const {
45 return hybrid_slow_start_
;
49 QuicConnectionStats stats_
;
51 using TcpCubicSender::SendWindow
;
54 class TcpCubicSenderTest
: public ::testing::Test
{
57 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
58 sender_(new TcpCubicSenderPeer(&clock_
, true,
59 kDefaultMaxCongestionWindowTCP
)),
60 receiver_(new TcpReceiver()),
62 acked_sequence_number_(0),
64 standard_packet_
.bytes_sent
= kDefaultTCPMSS
;
67 int SendAvailableSendWindow() {
68 // Send as long as TimeUntilSend returns Zero.
70 bool can_send
= sender_
->TimeUntilSend(
71 clock_
.Now(), bytes_in_flight_
, HAS_RETRANSMITTABLE_DATA
).IsZero();
73 sender_
->OnPacketSent(clock_
.Now(), bytes_in_flight_
, sequence_number_
++,
74 kDefaultTCPMSS
, HAS_RETRANSMITTABLE_DATA
);
76 bytes_in_flight_
+= kDefaultTCPMSS
;
77 can_send
= sender_
->TimeUntilSend(
78 clock_
.Now(), bytes_in_flight_
, HAS_RETRANSMITTABLE_DATA
).IsZero();
83 // Normal is that TCP acks every other segment.
84 void AckNPackets(int n
) {
85 sender_
->rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
86 QuicTime::Delta::Zero(),
88 SendAlgorithmInterface::CongestionMap acked_packets
;
89 SendAlgorithmInterface::CongestionMap lost_packets
;
90 for (int i
= 0; i
< n
; ++i
) {
91 ++acked_sequence_number_
;
92 acked_packets
[acked_sequence_number_
] = standard_packet_
;
94 sender_
->OnCongestionEvent(
95 true, bytes_in_flight_
, acked_packets
, lost_packets
);
96 bytes_in_flight_
-= n
* kDefaultTCPMSS
;
97 clock_
.AdvanceTime(one_ms_
);
100 void LoseNPackets(int n
) {
101 SendAlgorithmInterface::CongestionMap acked_packets
;
102 SendAlgorithmInterface::CongestionMap lost_packets
;
103 for (int i
= 0; i
< n
; ++i
) {
104 ++acked_sequence_number_
;
105 lost_packets
[acked_sequence_number_
] = standard_packet_
;
107 sender_
->OnCongestionEvent(
108 false, bytes_in_flight_
, acked_packets
, lost_packets
);
109 bytes_in_flight_
-= n
* kDefaultTCPMSS
;
112 // Does not increment acked_sequence_number_.
113 void LosePacket(QuicPacketSequenceNumber sequence_number
) {
114 SendAlgorithmInterface::CongestionMap acked_packets
;
115 SendAlgorithmInterface::CongestionMap lost_packets
;
116 lost_packets
[sequence_number
] = standard_packet_
;
117 sender_
->OnCongestionEvent(
118 false, bytes_in_flight_
, acked_packets
, lost_packets
);
119 bytes_in_flight_
-= kDefaultTCPMSS
;
122 const QuicTime::Delta one_ms_
;
124 scoped_ptr
<TcpCubicSenderPeer
> sender_
;
125 scoped_ptr
<TcpReceiver
> receiver_
;
126 QuicPacketSequenceNumber sequence_number_
;
127 QuicPacketSequenceNumber acked_sequence_number_
;
128 QuicByteCount bytes_in_flight_
;
129 TransmissionInfo standard_packet_
;
132 TEST_F(TcpCubicSenderTest
, SimpleSender
) {
133 QuicCongestionFeedbackFrame feedback
;
134 // At startup make sure we are at the default.
135 EXPECT_EQ(kDefaultWindowTCP
, sender_
->GetCongestionWindow());
136 // At startup make sure we can send.
137 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
139 HAS_RETRANSMITTABLE_DATA
).IsZero());
140 // Get default QuicCongestionFeedbackFrame from receiver.
141 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
142 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
143 // Make sure we can send.
144 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
146 HAS_RETRANSMITTABLE_DATA
).IsZero());
147 // And that window is un-affected.
148 EXPECT_EQ(kDefaultWindowTCP
, sender_
->GetCongestionWindow());
150 // Fill the send window with data, then verify that we can't send.
151 SendAvailableSendWindow();
152 EXPECT_FALSE(sender_
->TimeUntilSend(clock_
.Now(),
153 sender_
->GetCongestionWindow(),
154 HAS_RETRANSMITTABLE_DATA
).IsZero());
157 TEST_F(TcpCubicSenderTest
, ApplicationLimitedSlowStart
) {
158 // Send exactly 10 packets and ensure the CWND ends at 14 packets.
159 const int kNumberOfAcks
= 5;
160 QuicCongestionFeedbackFrame feedback
;
161 // At startup make sure we can send.
162 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
164 HAS_RETRANSMITTABLE_DATA
).IsZero());
165 // Get default QuicCongestionFeedbackFrame from receiver.
166 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
167 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
168 // Make sure we can send.
169 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
171 HAS_RETRANSMITTABLE_DATA
).IsZero());
173 SendAvailableSendWindow();
174 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
177 QuicByteCount bytes_to_send
= sender_
->SendWindow();
178 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
180 EXPECT_EQ(kDefaultWindowTCP
+ kDefaultTCPMSS
* 2 * 2,
184 TEST_F(TcpCubicSenderTest
, ExponentialSlowStart
) {
185 const int kNumberOfAcks
= 20;
186 QuicCongestionFeedbackFrame feedback
;
187 // At startup make sure we can send.
188 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
190 HAS_RETRANSMITTABLE_DATA
).IsZero());
191 // Get default QuicCongestionFeedbackFrame from receiver.
192 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
193 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
194 // Make sure we can send.
195 EXPECT_TRUE(sender_
->TimeUntilSend(clock_
.Now(),
197 HAS_RETRANSMITTABLE_DATA
).IsZero());
199 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
200 // Send our full send window.
201 SendAvailableSendWindow();
204 QuicByteCount bytes_to_send
= sender_
->SendWindow();
205 EXPECT_EQ(kDefaultWindowTCP
+ kDefaultTCPMSS
* 2 * kNumberOfAcks
,
209 TEST_F(TcpCubicSenderTest
, SlowStartAckTrain
) {
210 // Make sure that we fall out of slow start when we send ACK train longer
211 // than half the RTT, in this test case 30ms, which is more than 30 calls to
212 // Ack2Packets in one round.
213 // Since we start at 10 packet first round will be 5 second round 10 etc
214 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30
215 const int kNumberOfAcks
= 65;
216 QuicCongestionFeedbackFrame feedback
;
217 // Get default QuicCongestionFeedbackFrame from receiver.
218 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
219 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
221 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
222 // Send our full send window.
223 SendAvailableSendWindow();
226 QuicByteCount expected_send_window
=
227 kDefaultWindowTCP
+ (kDefaultTCPMSS
* 2 * kNumberOfAcks
);
228 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
230 // We should now have fallen out of slow start.
231 // Testing Reno phase.
232 // We should need 140(65*2+10) ACK:ed packets before increasing window by
234 for (int i
= 0; i
< 69; ++i
) {
235 SendAvailableSendWindow();
237 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
239 SendAvailableSendWindow();
241 expected_send_window
+= kDefaultTCPMSS
;
242 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
243 EXPECT_EQ(140u, sender_
->slowstart_threshold());
245 // Now RTO and ensure slow start gets reset.
246 EXPECT_TRUE(sender_
->hybrid_slow_start().started());
247 sender_
->OnRetransmissionTimeout(true);
248 EXPECT_FALSE(sender_
->hybrid_slow_start().started());
249 EXPECT_EQ(2 * kDefaultTCPMSS
, sender_
->GetCongestionWindow());
250 EXPECT_EQ(expected_send_window
/ 2 / kDefaultTCPMSS
,
251 sender_
->slowstart_threshold());
253 // Now revert the RTO and ensure the CWND and slowstart threshold revert.
254 sender_
->RevertRetransmissionTimeout();
255 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
256 EXPECT_EQ(140u, sender_
->slowstart_threshold());
259 TEST_F(TcpCubicSenderTest
, SlowStartPacketLoss
) {
260 // Make sure that we fall out of slow start when we encounter a packet loss.
261 QuicCongestionFeedbackFrame feedback
;
262 // Get default QuicCongestionFeedbackFrame from receiver.
263 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
264 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
266 const int kNumberOfAcks
= 10;
267 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
268 // Send our full send window.
269 SendAvailableSendWindow();
272 SendAvailableSendWindow();
273 QuicByteCount expected_send_window
= kDefaultWindowTCP
+
274 (kDefaultTCPMSS
* 2 * kNumberOfAcks
);
275 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
277 // Lose a packet to exit slow start.
280 // We should now have fallen out of slow start.
281 // We expect window to be cut in half by Reno.
282 expected_send_window
/= 2;
283 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
285 // Testing Reno phase.
286 // We need to ack half of the pending packet before we can send again.
287 size_t number_of_packets_in_window
= expected_send_window
/ kDefaultTCPMSS
;
288 AckNPackets(number_of_packets_in_window
);
289 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
291 // We need to ack every packet in the window before we exit recovery.
292 for (size_t i
= 0; i
< number_of_packets_in_window
; ++i
) {
294 SendAvailableSendWindow();
295 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
298 // We need to ack another window before we increase CWND by 1.
299 for (size_t i
= 0; i
< number_of_packets_in_window
- 2; ++i
) {
301 SendAvailableSendWindow();
302 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
306 expected_send_window
+= kDefaultTCPMSS
;
307 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
309 // Now RTO and ensure slow start gets reset.
310 EXPECT_TRUE(sender_
->hybrid_slow_start().started());
311 sender_
->OnRetransmissionTimeout(true);
312 EXPECT_FALSE(sender_
->hybrid_slow_start().started());
315 TEST_F(TcpCubicSenderTest
, SlowStartPacketLossPRR
) {
316 // Test based on the first example in RFC6937.
317 // Make sure that we fall out of slow start when we encounter a packet loss.
318 QuicCongestionFeedbackFrame feedback
;
319 // Get default QuicCongestionFeedbackFrame from receiver.
320 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
321 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
323 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
324 const int kNumberOfAcks
= 5;
325 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
326 // Send our full send window.
327 SendAvailableSendWindow();
330 SendAvailableSendWindow();
331 QuicByteCount expected_send_window
= kDefaultWindowTCP
+
332 (kDefaultTCPMSS
* 2 * kNumberOfAcks
);
333 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
337 // We should now have fallen out of slow start.
338 // We expect window to be cut in half by Reno.
339 expected_send_window
/= 2;
340 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
342 // Testing TCP proportional rate reduction.
343 // We should send one packet for every two received acks over the remaining
344 // 18 outstanding packets.
345 size_t number_of_packets_in_window
= expected_send_window
/ kDefaultTCPMSS
;
346 // The number of packets before we exit recovery is the original CWND minus
347 // the packet that has been lost and the one which triggered the loss.
348 size_t remaining_packets_in_recovery
= number_of_packets_in_window
* 2 - 1;
349 for (size_t i
= 0; i
< remaining_packets_in_recovery
- 1; i
+= 2) {
351 EXPECT_TRUE(sender_
->TimeUntilSend(
352 clock_
.Now(), bytes_in_flight_
, HAS_RETRANSMITTABLE_DATA
).IsZero());
353 EXPECT_EQ(1, SendAvailableSendWindow());
354 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
357 // We need to ack another window before we increase CWND by 1.
358 for (size_t i
= 0; i
< number_of_packets_in_window
; ++i
) {
360 EXPECT_EQ(1, SendAvailableSendWindow());
361 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
365 expected_send_window
+= kDefaultTCPMSS
;
366 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
369 TEST_F(TcpCubicSenderTest
, SlowStartBurstPacketLossPRR
) {
370 // Test based on the second example in RFC6937, though we also implement
371 // forward acknowledgements, so the first two incoming acks will trigger
373 // Make sure that we fall out of slow start when we encounter a packet loss.
374 QuicCongestionFeedbackFrame feedback
;
375 // Get default QuicCongestionFeedbackFrame from receiver.
376 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
377 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
379 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
380 const int kNumberOfAcks
= 5;
381 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
382 // Send our full send window.
383 SendAvailableSendWindow();
386 SendAvailableSendWindow();
387 QuicByteCount expected_send_window
= kDefaultWindowTCP
+
388 (kDefaultTCPMSS
* 2 * kNumberOfAcks
);
389 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
391 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK.
393 // Immediately after the loss, ensure at least one packet can be sent.
394 // Losses without subsequent acks can occur with timer based loss detection.
395 EXPECT_TRUE(sender_
->TimeUntilSend(
396 clock_
.Now(), bytes_in_flight_
, HAS_RETRANSMITTABLE_DATA
).IsZero());
399 // We should now have fallen out of slow start.
400 // We expect window to be cut in half by Reno.
401 expected_send_window
/= 2;
402 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
404 // Only 2 packets should be allowed to be sent, per PRR-SSRB
405 EXPECT_EQ(2, SendAvailableSendWindow());
407 // Ack the next packet, which triggers another loss.
411 // Send 2 packets to simulate PRR-SSRB.
412 EXPECT_EQ(2, SendAvailableSendWindow());
414 // Ack the next packet, which triggers another loss.
418 // Send 2 packets to simulate PRR-SSRB.
419 EXPECT_EQ(2, SendAvailableSendWindow());
422 EXPECT_EQ(2, SendAvailableSendWindow());
425 EXPECT_EQ(2, SendAvailableSendWindow());
427 // The window should not have changed.
428 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
430 // Exit recovery and return to sending at the new rate.
431 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
433 EXPECT_EQ(1, SendAvailableSendWindow());
437 TEST_F(TcpCubicSenderTest
, RTOCongestionWindowAndRevert
) {
438 EXPECT_EQ(kDefaultWindowTCP
, sender_
->SendWindow());
439 EXPECT_EQ(10000u, sender_
->slowstart_threshold());
441 // Expect the window to decrease to the minimum once the RTO fires
442 // and slow start threshold to be set to 1/2 of the CWND.
443 sender_
->OnRetransmissionTimeout(true);
444 EXPECT_EQ(2 * kDefaultTCPMSS
, sender_
->SendWindow());
445 EXPECT_EQ(5u, sender_
->slowstart_threshold());
447 // Now repair the RTO and ensure the slowstart threshold reverts.
448 sender_
->RevertRetransmissionTimeout();
449 EXPECT_EQ(kDefaultWindowTCP
, sender_
->SendWindow());
450 EXPECT_EQ(10000u, sender_
->slowstart_threshold());
453 TEST_F(TcpCubicSenderTest
, RTOCongestionWindowNoRetransmission
) {
454 EXPECT_EQ(kDefaultWindowTCP
, sender_
->SendWindow());
456 // Expect the window to remain unchanged if the RTO fires but no
457 // packets are retransmitted.
458 sender_
->OnRetransmissionTimeout(false);
459 EXPECT_EQ(kDefaultWindowTCP
, sender_
->SendWindow());
462 TEST_F(TcpCubicSenderTest
, RetransmissionDelay
) {
463 const int64 kRttMs
= 10;
464 const int64 kDeviationMs
= 3;
465 EXPECT_EQ(QuicTime::Delta::Zero(), sender_
->RetransmissionDelay());
467 sender_
->rtt_stats_
.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs
),
468 QuicTime::Delta::Zero(), clock_
.Now());
470 // Initial value is to set the median deviation to half of the initial
471 // rtt, the median in then multiplied by a factor of 4 and finally the
472 // smoothed rtt is added which is the initial rtt.
473 QuicTime::Delta expected_delay
=
474 QuicTime::Delta::FromMilliseconds(kRttMs
+ kRttMs
/ 2 * 4);
475 EXPECT_EQ(expected_delay
, sender_
->RetransmissionDelay());
477 for (int i
= 0; i
< 100; ++i
) {
478 // Run to make sure that we converge.
479 sender_
->rtt_stats_
.UpdateRtt(
480 QuicTime::Delta::FromMilliseconds(kRttMs
+ kDeviationMs
),
481 QuicTime::Delta::Zero(), clock_
.Now());
482 sender_
->rtt_stats_
.UpdateRtt(
483 QuicTime::Delta::FromMilliseconds(kRttMs
- kDeviationMs
),
484 QuicTime::Delta::Zero(), clock_
.Now());
486 expected_delay
= QuicTime::Delta::FromMilliseconds(kRttMs
+ kDeviationMs
* 4);
488 EXPECT_NEAR(kRttMs
, sender_
->rtt_stats_
.SmoothedRtt().ToMilliseconds(), 1);
489 EXPECT_NEAR(expected_delay
.ToMilliseconds(),
490 sender_
->RetransmissionDelay().ToMilliseconds(),
492 EXPECT_EQ(static_cast<int64
>(
493 sender_
->GetCongestionWindow() * kNumMicrosPerSecond
/
494 sender_
->rtt_stats_
.SmoothedRtt().ToMicroseconds()),
495 sender_
->BandwidthEstimate().ToBytesPerSecond());
498 TEST_F(TcpCubicSenderTest
, SlowStartMaxSendWindow
) {
499 const QuicTcpCongestionWindow kMaxCongestionWindowTCP
= 50;
500 const int kNumberOfAcks
= 100;
502 new TcpCubicSenderPeer(&clock_
, false, kMaxCongestionWindowTCP
));
504 QuicCongestionFeedbackFrame feedback
;
505 // Get default QuicCongestionFeedbackFrame from receiver.
506 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
507 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
509 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
510 // Send our full send window.
511 SendAvailableSendWindow();
514 QuicByteCount expected_send_window
=
515 kMaxCongestionWindowTCP
* kDefaultTCPMSS
;
516 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
519 TEST_F(TcpCubicSenderTest
, TcpRenoMaxCongestionWindow
) {
520 const QuicTcpCongestionWindow kMaxCongestionWindowTCP
= 50;
521 const int kNumberOfAcks
= 1000;
523 new TcpCubicSenderPeer(&clock_
, true, kMaxCongestionWindowTCP
));
525 QuicCongestionFeedbackFrame feedback
;
526 // Get default QuicCongestionFeedbackFrame from receiver.
527 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
528 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
530 SendAvailableSendWindow();
532 // Make sure we fall out of slow start.
535 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
536 // Send our full send window.
537 SendAvailableSendWindow();
541 QuicByteCount expected_send_window
=
542 kMaxCongestionWindowTCP
* kDefaultTCPMSS
;
543 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
546 TEST_F(TcpCubicSenderTest
, TcpCubicMaxCongestionWindow
) {
547 const QuicTcpCongestionWindow kMaxCongestionWindowTCP
= 50;
548 // Set to 10000 to compensate for small cubic alpha.
549 const int kNumberOfAcks
= 10000;
552 new TcpCubicSenderPeer(&clock_
, false, kMaxCongestionWindowTCP
));
554 QuicCongestionFeedbackFrame feedback
;
555 // Get default QuicCongestionFeedbackFrame from receiver.
556 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
557 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
559 SendAvailableSendWindow();
561 // Make sure we fall out of slow start.
564 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
565 // Send our full send window.
566 SendAvailableSendWindow();
570 QuicByteCount expected_send_window
=
571 kMaxCongestionWindowTCP
* kDefaultTCPMSS
;
572 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
575 TEST_F(TcpCubicSenderTest
, MultipleLossesInOneWindow
) {
576 SendAvailableSendWindow();
577 const QuicByteCount initial_window
= sender_
->GetCongestionWindow();
578 LosePacket(acked_sequence_number_
+ 1);
579 const QuicByteCount post_loss_window
= sender_
->GetCongestionWindow();
580 EXPECT_GT(initial_window
, post_loss_window
);
581 LosePacket(acked_sequence_number_
+ 3);
582 EXPECT_EQ(post_loss_window
, sender_
->GetCongestionWindow());
583 LosePacket(sequence_number_
- 1);
584 EXPECT_EQ(post_loss_window
, sender_
->GetCongestionWindow());
586 // Lose a later packet and ensure the window decreases.
587 LosePacket(sequence_number_
);
588 EXPECT_GT(post_loss_window
, sender_
->GetCongestionWindow());
591 TEST_F(TcpCubicSenderTest
, DontTrackAckPackets
) {
592 // Send a packet with no retransmittable data, and ensure it's not tracked.
593 EXPECT_FALSE(sender_
->OnPacketSent(clock_
.Now(), bytes_in_flight_
,
594 sequence_number_
++, kDefaultTCPMSS
,
595 NO_RETRANSMITTABLE_DATA
));
597 // Send a data packet with retransmittable data, and ensure it is tracked.
598 EXPECT_TRUE(sender_
->OnPacketSent(clock_
.Now(), bytes_in_flight_
,
599 sequence_number_
++, kDefaultTCPMSS
,
600 HAS_RETRANSMITTABLE_DATA
));
603 TEST_F(TcpCubicSenderTest
, ConfigureMaxInitialWindow
) {
604 QuicTcpCongestionWindow congestion_window
= sender_
->congestion_window();
606 QuicConfigPeer::SetReceivedInitialWindow(&config
, 2 * congestion_window
);
608 sender_
->SetFromConfig(config
, true);
609 EXPECT_EQ(2 * congestion_window
, sender_
->congestion_window());
612 TEST_F(TcpCubicSenderTest
, CongestionAvoidanceAtEndOfRecovery
) {
613 // Make sure that we fall out of slow start when we encounter a packet loss.
614 QuicCongestionFeedbackFrame feedback
;
615 // Get default QuicCongestionFeedbackFrame from receiver.
616 ASSERT_TRUE(receiver_
->GenerateCongestionFeedback(&feedback
));
617 sender_
->OnIncomingQuicCongestionFeedbackFrame(feedback
, clock_
.Now());
618 // Ack 10 packets in 5 acks to raise the CWND to 20.
619 const int kNumberOfAcks
= 5;
620 for (int i
= 0; i
< kNumberOfAcks
; ++i
) {
621 // Send our full send window.
622 SendAvailableSendWindow();
625 SendAvailableSendWindow();
626 QuicByteCount expected_send_window
= kDefaultWindowTCP
+
627 (kDefaultTCPMSS
* 2 * kNumberOfAcks
);
628 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
632 // We should now have fallen out of slow start, and window should be cut in
633 // half by Reno. New cwnd should be 10.
634 expected_send_window
/= 2;
635 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
637 // No congestion window growth should occur in recovery phase, i.e.,
638 // until the currently outstanding 20 packets are acked.
639 for (int i
= 0; i
< 10; ++i
) {
640 // Send our full send window.
641 SendAvailableSendWindow();
643 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
646 // Out of recovery now. Congestion window should not grow during RTT.
647 for (int i
= 0; i
< 4; ++i
) {
648 // Send our full send window.
649 SendAvailableSendWindow();
651 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());
654 // Next ack should cause congestion window to grow by 1MSS.
656 expected_send_window
+= kDefaultTCPMSS
;
657 EXPECT_EQ(expected_send_window
, sender_
->GetCongestionWindow());