Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / net / quic / congestion_control / tcp_cubic_sender_test.cc
blob8409f97283302b4ba39081187c822057406ab875
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.
5 #include <algorithm>
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"
17 using std::min;
19 namespace net {
20 namespace test {
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 {
28 public:
29 TcpCubicSenderPeer(const QuicClock* clock,
30 bool reno,
31 QuicTcpCongestionWindow max_tcp_congestion_window)
32 : TcpCubicSender(
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_;
48 RttStats rtt_stats_;
49 QuicConnectionStats stats_;
51 using TcpCubicSender::SendWindow;
54 class TcpCubicSenderTest : public ::testing::Test {
55 protected:
56 TcpCubicSenderTest()
57 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
58 sender_(new TcpCubicSenderPeer(&clock_, true,
59 kDefaultMaxCongestionWindowTCP)),
60 receiver_(new TcpReceiver()),
61 sequence_number_(1),
62 acked_sequence_number_(0),
63 bytes_in_flight_(0) {
64 standard_packet_.bytes_sent = kDefaultTCPMSS;
67 int SendAvailableSendWindow() {
68 // Send as long as TimeUntilSend returns Zero.
69 int packets_sent = 0;
70 bool can_send = sender_->TimeUntilSend(
71 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
72 while (can_send) {
73 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++,
74 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
75 ++packets_sent;
76 bytes_in_flight_ += kDefaultTCPMSS;
77 can_send = sender_->TimeUntilSend(
78 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
80 return packets_sent;
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(),
87 clock_.Now());
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_;
123 MockClock clock_;
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) {
175 AckNPackets(2);
177 QuicByteCount bytes_to_send = sender_->SendWindow();
178 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
179 // half the CWND.
180 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
181 bytes_to_send);
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();
202 AckNPackets(2);
204 QuicByteCount bytes_to_send = sender_->SendWindow();
205 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks,
206 bytes_to_send);
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();
224 AckNPackets(2);
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
233 // one.
234 for (int i = 0; i < 69; ++i) {
235 SendAvailableSendWindow();
236 AckNPackets(2);
237 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
239 SendAvailableSendWindow();
240 AckNPackets(2);
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();
270 AckNPackets(2);
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.
278 LoseNPackets(1);
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) {
293 AckNPackets(1);
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) {
300 AckNPackets(1);
301 SendAvailableSendWindow();
302 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
305 AckNPackets(1);
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();
328 AckNPackets(2);
330 SendAvailableSendWindow();
331 QuicByteCount expected_send_window = kDefaultWindowTCP +
332 (kDefaultTCPMSS * 2 * kNumberOfAcks);
333 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
335 LoseNPackets(1);
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) {
350 AckNPackets(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) {
359 AckNPackets(1);
360 EXPECT_EQ(1, SendAvailableSendWindow());
361 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
364 AckNPackets(1);
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
372 // PRR immediately.
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();
384 AckNPackets(2);
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.
392 LoseNPackets(13);
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());
397 AckNPackets(1);
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.
408 LoseNPackets(1);
409 AckNPackets(1);
411 // Send 2 packets to simulate PRR-SSRB.
412 EXPECT_EQ(2, SendAvailableSendWindow());
414 // Ack the next packet, which triggers another loss.
415 LoseNPackets(1);
416 AckNPackets(1);
418 // Send 2 packets to simulate PRR-SSRB.
419 EXPECT_EQ(2, SendAvailableSendWindow());
421 AckNPackets(1);
422 EXPECT_EQ(2, SendAvailableSendWindow());
424 AckNPackets(1);
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) {
432 AckNPackets(1);
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;
501 sender_.reset(
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();
512 AckNPackets(2);
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;
522 sender_.reset(
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();
531 AckNPackets(2);
532 // Make sure we fall out of slow start.
533 LoseNPackets(1);
535 for (int i = 0; i < kNumberOfAcks; ++i) {
536 // Send our full send window.
537 SendAvailableSendWindow();
538 AckNPackets(2);
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;
551 sender_.reset(
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();
560 AckNPackets(2);
561 // Make sure we fall out of slow start.
562 LoseNPackets(1);
564 for (int i = 0; i < kNumberOfAcks; ++i) {
565 // Send our full send window.
566 SendAvailableSendWindow();
567 AckNPackets(2);
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();
605 QuicConfig config;
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();
623 AckNPackets(2);
625 SendAvailableSendWindow();
626 QuicByteCount expected_send_window = kDefaultWindowTCP +
627 (kDefaultTCPMSS * 2 * kNumberOfAcks);
628 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
630 LoseNPackets(1);
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();
642 AckNPackets(2);
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();
650 AckNPackets(2);
651 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
654 // Next ack should cause congestion window to grow by 1MSS.
655 AckNPackets(2);
656 expected_send_window += kDefaultTCPMSS;
657 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
660 } // namespace test
661 } // namespace net