Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / quic / congestion_control / tcp_cubic_sender_test.cc
blob90773b3e5beeb3349af81daba3c4d671ce2900a7
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/crypto/crypto_protocol.h"
12 #include "net/quic/proto/cached_network_parameters.pb.h"
13 #include "net/quic/quic_protocol.h"
14 #include "net/quic/quic_utils.h"
15 #include "net/quic/test_tools/mock_clock.h"
16 #include "net/quic/test_tools/quic_config_peer.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using std::min;
21 namespace net {
22 namespace test {
24 // TODO(ianswett): A number of theses tests were written with the assumption of
25 // an initial CWND of 10. They have carefully calculated values which should be
26 // updated to be based on kInitialCongestionWindowInsecure.
27 const uint32 kInitialCongestionWindowPackets = 10;
28 const uint32 kDefaultWindowTCP =
29 kInitialCongestionWindowPackets * kDefaultTCPMSS;
30 const float kRenoBeta = 0.7f; // Reno backoff factor.
32 class TcpCubicSenderPeer : public TcpCubicSender {
33 public:
34 TcpCubicSenderPeer(const QuicClock* clock,
35 bool reno,
36 QuicPacketCount max_tcp_congestion_window)
37 : TcpCubicSender(clock,
38 &rtt_stats_,
39 reno,
40 kInitialCongestionWindowPackets,
41 max_tcp_congestion_window,
42 &stats_) {}
44 QuicPacketCount congestion_window() {
45 return congestion_window_;
48 QuicPacketCount slowstart_threshold() {
49 return slowstart_threshold_;
52 const HybridSlowStart& hybrid_slow_start() const {
53 return hybrid_slow_start_;
56 float GetRenoBeta() const {
57 return RenoBeta();
60 RttStats rtt_stats_;
61 QuicConnectionStats stats_;
64 class TcpCubicSenderTest : public ::testing::Test {
65 protected:
66 TcpCubicSenderTest()
67 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
68 sender_(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindow)),
69 sequence_number_(1),
70 acked_sequence_number_(0),
71 bytes_in_flight_(0) {
72 standard_packet_.bytes_sent = kDefaultTCPMSS;
75 int SendAvailableSendWindow() {
76 // Send as long as TimeUntilSend returns Zero.
77 int packets_sent = 0;
78 bool can_send = sender_->TimeUntilSend(
79 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
80 while (can_send) {
81 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++,
82 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
83 ++packets_sent;
84 bytes_in_flight_ += kDefaultTCPMSS;
85 can_send = sender_->TimeUntilSend(
86 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
88 return packets_sent;
91 // Normal is that TCP acks every other segment.
92 void AckNPackets(int n) {
93 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
94 QuicTime::Delta::Zero(),
95 clock_.Now());
96 SendAlgorithmInterface::CongestionVector acked_packets;
97 SendAlgorithmInterface::CongestionVector lost_packets;
98 for (int i = 0; i < n; ++i) {
99 ++acked_sequence_number_;
100 acked_packets.push_back(
101 std::make_pair(acked_sequence_number_, standard_packet_));
103 sender_->OnCongestionEvent(
104 true, bytes_in_flight_, acked_packets, lost_packets);
105 bytes_in_flight_ -= n * kDefaultTCPMSS;
106 clock_.AdvanceTime(one_ms_);
109 void LoseNPackets(int n) {
110 SendAlgorithmInterface::CongestionVector acked_packets;
111 SendAlgorithmInterface::CongestionVector lost_packets;
112 for (int i = 0; i < n; ++i) {
113 ++acked_sequence_number_;
114 lost_packets.push_back(
115 std::make_pair(acked_sequence_number_, standard_packet_));
117 sender_->OnCongestionEvent(
118 false, bytes_in_flight_, acked_packets, lost_packets);
119 bytes_in_flight_ -= n * kDefaultTCPMSS;
122 // Does not increment acked_sequence_number_.
123 void LosePacket(QuicPacketSequenceNumber sequence_number) {
124 SendAlgorithmInterface::CongestionVector acked_packets;
125 SendAlgorithmInterface::CongestionVector lost_packets;
126 lost_packets.push_back(std::make_pair(sequence_number, standard_packet_));
127 sender_->OnCongestionEvent(
128 false, bytes_in_flight_, acked_packets, lost_packets);
129 bytes_in_flight_ -= kDefaultTCPMSS;
132 const QuicTime::Delta one_ms_;
133 MockClock clock_;
134 scoped_ptr<TcpCubicSenderPeer> sender_;
135 QuicPacketSequenceNumber sequence_number_;
136 QuicPacketSequenceNumber acked_sequence_number_;
137 QuicByteCount bytes_in_flight_;
138 TransmissionInfo standard_packet_;
141 TEST_F(TcpCubicSenderTest, SimpleSender) {
142 // At startup make sure we are at the default.
143 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
144 // At startup make sure we can send.
145 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
147 HAS_RETRANSMITTABLE_DATA).IsZero());
148 // Make sure we can send.
149 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
151 HAS_RETRANSMITTABLE_DATA).IsZero());
152 // And that window is un-affected.
153 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
155 // Fill the send window with data, then verify that we can't send.
156 SendAvailableSendWindow();
157 EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
158 sender_->GetCongestionWindow(),
159 HAS_RETRANSMITTABLE_DATA).IsZero());
162 TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
163 // Send exactly 10 packets and ensure the CWND ends at 14 packets.
164 const int kNumberOfAcks = 5;
165 // At startup make sure we can send.
166 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
168 HAS_RETRANSMITTABLE_DATA).IsZero());
169 // Make sure we can send.
170 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
172 HAS_RETRANSMITTABLE_DATA).IsZero());
174 SendAvailableSendWindow();
175 for (int i = 0; i < kNumberOfAcks; ++i) {
176 AckNPackets(2);
178 QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
179 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
180 // half the CWND.
181 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
182 bytes_to_send);
185 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
186 const int kNumberOfAcks = 20;
187 // At startup make sure we can send.
188 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
190 HAS_RETRANSMITTABLE_DATA).IsZero());
191 EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
192 // Make sure we can send.
193 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
195 HAS_RETRANSMITTABLE_DATA).IsZero());
197 for (int i = 0; i < kNumberOfAcks; ++i) {
198 // Send our full send window.
199 SendAvailableSendWindow();
200 AckNPackets(2);
202 const QuicByteCount cwnd = sender_->GetCongestionWindow();
203 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
204 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
205 cwnd, sender_->rtt_stats_.smoothed_rtt()),
206 sender_->BandwidthEstimate());
209 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
210 sender_->SetNumEmulatedConnections(1);
211 const int kNumberOfAcks = 10;
212 for (int i = 0; i < kNumberOfAcks; ++i) {
213 // Send our full send window.
214 SendAvailableSendWindow();
215 AckNPackets(2);
217 SendAvailableSendWindow();
218 QuicByteCount expected_send_window = kDefaultWindowTCP +
219 (kDefaultTCPMSS * 2 * kNumberOfAcks);
220 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
222 // Lose a packet to exit slow start.
223 LoseNPackets(1);
224 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
226 // We should now have fallen out of slow start with a reduced window.
227 expected_send_window *= kRenoBeta;
228 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
230 // Recovery phase. We need to ack every packet in the recovery window before
231 // we exit recovery.
232 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
233 DVLOG(1) << "number_packets: " << number_of_packets_in_window;
234 AckNPackets(packets_in_recovery_window);
235 SendAvailableSendWindow();
236 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
238 // We need to ack an entire window before we increase CWND by 1.
239 AckNPackets(number_of_packets_in_window - 2);
240 SendAvailableSendWindow();
241 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
243 // Next ack should increase cwnd by 1.
244 AckNPackets(1);
245 expected_send_window += kDefaultTCPMSS;
246 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
248 // Now RTO and ensure slow start gets reset.
249 EXPECT_TRUE(sender_->hybrid_slow_start().started());
250 sender_->OnRetransmissionTimeout(true);
251 EXPECT_FALSE(sender_->hybrid_slow_start().started());
254 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
255 SendAvailableSendWindow();
256 LoseNPackets(kInitialCongestionWindowPackets - 1);
257 AckNPackets(1);
258 // PRR will allow 2 packets for every ack during recovery.
259 EXPECT_EQ(2, SendAvailableSendWindow());
260 // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
261 // PRR should now allow a packet to be sent, even though prr's state
262 // variables believe it has sent enough packets.
263 EXPECT_EQ(QuicTime::Delta::Zero(),
264 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA));
267 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
268 sender_->SetNumEmulatedConnections(1);
269 // Test based on the first example in RFC6937.
270 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
271 const int kNumberOfAcks = 5;
272 for (int i = 0; i < kNumberOfAcks; ++i) {
273 // Send our full send window.
274 SendAvailableSendWindow();
275 AckNPackets(2);
277 SendAvailableSendWindow();
278 QuicByteCount expected_send_window = kDefaultWindowTCP +
279 (kDefaultTCPMSS * 2 * kNumberOfAcks);
280 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
282 LoseNPackets(1);
284 // We should now have fallen out of slow start with a reduced window.
285 size_t send_window_before_loss = expected_send_window;
286 expected_send_window *= kRenoBeta;
287 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
289 // Testing TCP proportional rate reduction.
290 // We should send packets paced over the received acks for the remaining
291 // outstanding packets. The number of packets before we exit recovery is the
292 // original CWND minus the packet that has been lost and the one which
293 // triggered the loss.
294 size_t remaining_packets_in_recovery =
295 send_window_before_loss / kDefaultTCPMSS - 2;
297 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
298 AckNPackets(1);
299 SendAvailableSendWindow();
300 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
303 // We need to ack another window before we increase CWND by 1.
304 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
305 for (size_t i = 0; i < number_of_packets_in_window; ++i) {
306 AckNPackets(1);
307 EXPECT_EQ(1, SendAvailableSendWindow());
308 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
311 AckNPackets(1);
312 expected_send_window += kDefaultTCPMSS;
313 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
316 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
317 sender_->SetNumEmulatedConnections(1);
318 // Test based on the second example in RFC6937, though we also implement
319 // forward acknowledgements, so the first two incoming acks will trigger
320 // PRR immediately.
321 // Ack 20 packets in 10 acks to raise the CWND to 30.
322 const int kNumberOfAcks = 10;
323 for (int i = 0; i < kNumberOfAcks; ++i) {
324 // Send our full send window.
325 SendAvailableSendWindow();
326 AckNPackets(2);
328 SendAvailableSendWindow();
329 QuicByteCount expected_send_window = kDefaultWindowTCP +
330 (kDefaultTCPMSS * 2 * kNumberOfAcks);
331 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
333 // Lose one more than the congestion window reduction, so that after loss,
334 // bytes_in_flight is lesser than the congestion window.
335 size_t send_window_after_loss = kRenoBeta * expected_send_window;
336 size_t num_packets_to_lose =
337 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
338 LoseNPackets(num_packets_to_lose);
339 // Immediately after the loss, ensure at least one packet can be sent.
340 // Losses without subsequent acks can occur with timer based loss detection.
341 EXPECT_TRUE(sender_->TimeUntilSend(
342 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
343 AckNPackets(1);
345 // We should now have fallen out of slow start with a reduced window.
346 expected_send_window *= kRenoBeta;
347 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
349 // Only 2 packets should be allowed to be sent, per PRR-SSRB
350 EXPECT_EQ(2, SendAvailableSendWindow());
352 // Ack the next packet, which triggers another loss.
353 LoseNPackets(1);
354 AckNPackets(1);
356 // Send 2 packets to simulate PRR-SSRB.
357 EXPECT_EQ(2, SendAvailableSendWindow());
359 // Ack the next packet, which triggers another loss.
360 LoseNPackets(1);
361 AckNPackets(1);
363 // Send 2 packets to simulate PRR-SSRB.
364 EXPECT_EQ(2, SendAvailableSendWindow());
366 // Exit recovery and return to sending at the new rate.
367 for (int i = 0; i < kNumberOfAcks; ++i) {
368 AckNPackets(1);
369 EXPECT_EQ(1, SendAvailableSendWindow());
373 TEST_F(TcpCubicSenderTest, RTOCongestionWindow) {
374 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
375 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold());
377 // Expect the window to decrease to the minimum once the RTO fires
378 // and slow start threshold to be set to 1/2 of the CWND.
379 sender_->OnRetransmissionTimeout(true);
380 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
381 EXPECT_EQ(5u, sender_->slowstart_threshold());
384 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
385 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
387 // Expect the window to remain unchanged if the RTO fires but no
388 // packets are retransmitted.
389 sender_->OnRetransmissionTimeout(false);
390 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
393 TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
394 const int64 kRttMs = 10;
395 const int64 kDeviationMs = 3;
396 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
398 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
399 QuicTime::Delta::Zero(), clock_.Now());
401 // Initial value is to set the median deviation to half of the initial
402 // rtt, the median in then multiplied by a factor of 4 and finally the
403 // smoothed rtt is added which is the initial rtt.
404 QuicTime::Delta expected_delay =
405 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
406 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
408 for (int i = 0; i < 100; ++i) {
409 // Run to make sure that we converge.
410 sender_->rtt_stats_.UpdateRtt(
411 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
412 QuicTime::Delta::Zero(), clock_.Now());
413 sender_->rtt_stats_.UpdateRtt(
414 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
415 QuicTime::Delta::Zero(), clock_.Now());
417 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
419 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
420 EXPECT_NEAR(expected_delay.ToMilliseconds(),
421 sender_->RetransmissionDelay().ToMilliseconds(),
423 EXPECT_EQ(static_cast<int64>(
424 sender_->GetCongestionWindow() * kNumMicrosPerSecond /
425 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
426 sender_->BandwidthEstimate().ToBytesPerSecond());
429 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) {
430 const QuicPacketCount kMaxCongestionWindowTCP = 50;
431 const int kNumberOfAcks = 100;
432 sender_.reset(
433 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
435 for (int i = 0; i < kNumberOfAcks; ++i) {
436 // Send our full send window.
437 SendAvailableSendWindow();
438 AckNPackets(2);
440 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
441 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
444 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) {
445 const QuicPacketCount kMaxCongestionWindowTCP = 50;
446 const int kNumberOfAcks = 1000;
447 sender_.reset(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP));
449 SendAvailableSendWindow();
450 AckNPackets(2);
451 // Make sure we fall out of slow start.
452 LoseNPackets(1);
454 for (int i = 0; i < kNumberOfAcks; ++i) {
455 // Send our full send window.
456 SendAvailableSendWindow();
457 AckNPackets(2);
460 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
461 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
464 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) {
465 const QuicPacketCount kMaxCongestionWindowTCP = 50;
466 // Set to 10000 to compensate for small cubic alpha.
467 const int kNumberOfAcks = 10000;
469 sender_.reset(
470 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
472 SendAvailableSendWindow();
473 AckNPackets(2);
474 // Make sure we fall out of slow start.
475 LoseNPackets(1);
477 for (int i = 0; i < kNumberOfAcks; ++i) {
478 // Send our full send window.
479 SendAvailableSendWindow();
480 AckNPackets(2);
483 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
484 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
487 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
488 SendAvailableSendWindow();
489 const QuicByteCount initial_window = sender_->GetCongestionWindow();
490 LosePacket(acked_sequence_number_ + 1);
491 const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
492 EXPECT_GT(initial_window, post_loss_window);
493 LosePacket(acked_sequence_number_ + 3);
494 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
495 LosePacket(sequence_number_ - 1);
496 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
498 // Lose a later packet and ensure the window decreases.
499 LosePacket(sequence_number_);
500 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
503 TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
504 // Send a packet with no retransmittable data, and ensure it's not tracked.
505 EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
506 sequence_number_++, kDefaultTCPMSS,
507 NO_RETRANSMITTABLE_DATA));
509 // Send a data packet with retransmittable data, and ensure it is tracked.
510 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
511 sequence_number_++, kDefaultTCPMSS,
512 HAS_RETRANSMITTABLE_DATA));
515 TEST_F(TcpCubicSenderTest, ConfigureInitialWindow) {
516 QuicConfig config;
518 QuicTagVector options;
519 options.push_back(kIW03);
520 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
521 sender_->SetFromConfig(config, Perspective::IS_SERVER);
522 EXPECT_EQ(3u, sender_->congestion_window());
524 options.clear();
525 options.push_back(kIW10);
526 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
527 sender_->SetFromConfig(config, Perspective::IS_SERVER);
528 EXPECT_EQ(10u, sender_->congestion_window());
530 options.clear();
531 options.push_back(kIW20);
532 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
533 sender_->SetFromConfig(config, Perspective::IS_SERVER);
534 EXPECT_EQ(20u, sender_->congestion_window());
536 options.clear();
537 options.push_back(kIW50);
538 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
539 sender_->SetFromConfig(config, Perspective::IS_SERVER);
540 EXPECT_EQ(50u, sender_->congestion_window());
543 TEST_F(TcpCubicSenderTest, ConfigureMinimumWindow) {
544 QuicConfig config;
546 // Verify that kCOPT: kMIN1 forces the min CWND to 1 packet.
547 QuicTagVector options;
548 options.push_back(kMIN1);
549 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
550 sender_->SetFromConfig(config, Perspective::IS_SERVER);
551 sender_->OnRetransmissionTimeout(true);
552 EXPECT_EQ(1u, sender_->congestion_window());
555 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
556 sender_->SetNumEmulatedConnections(2);
557 // Ack 10 packets in 5 acks to raise the CWND to 20.
558 const int kNumberOfAcks = 5;
559 for (int i = 0; i < kNumberOfAcks; ++i) {
560 // Send our full send window.
561 SendAvailableSendWindow();
562 AckNPackets(2);
564 SendAvailableSendWindow();
565 QuicByteCount expected_send_window = kDefaultWindowTCP +
566 (kDefaultTCPMSS * 2 * kNumberOfAcks);
567 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
569 LoseNPackets(1);
571 // We should now have fallen out of slow start with a reduced window.
572 expected_send_window = expected_send_window * sender_->GetRenoBeta();
573 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
575 // No congestion window growth should occur in recovery phase, i.e., until the
576 // currently outstanding 20 packets are acked.
577 for (int i = 0; i < 10; ++i) {
578 // Send our full send window.
579 SendAvailableSendWindow();
580 EXPECT_TRUE(sender_->InRecovery());
581 AckNPackets(2);
582 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
584 EXPECT_FALSE(sender_->InRecovery());
586 // Out of recovery now. Congestion window should not grow for half an RTT.
587 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
588 SendAvailableSendWindow();
589 AckNPackets(packets_in_send_window / 2 - 2);
590 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
592 // Next ack should increase congestion window by 1MSS.
593 SendAvailableSendWindow();
594 AckNPackets(2);
595 expected_send_window += kDefaultTCPMSS;
596 packets_in_send_window += 1;
597 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
599 // Congestion window should remain steady again for half an RTT.
600 SendAvailableSendWindow();
601 AckNPackets(packets_in_send_window / 2 - 1);
602 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
604 // Next ack should cause congestion window to grow by 1MSS.
605 SendAvailableSendWindow();
606 AckNPackets(2);
607 expected_send_window += kDefaultTCPMSS;
608 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
611 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
612 sender_->SetNumEmulatedConnections(1);
613 // Ack 10 packets in 5 acks to raise the CWND to 20.
614 const int kNumberOfAcks = 5;
615 for (int i = 0; i < kNumberOfAcks; ++i) {
616 // Send our full send window.
617 SendAvailableSendWindow();
618 AckNPackets(2);
620 SendAvailableSendWindow();
621 QuicByteCount expected_send_window = kDefaultWindowTCP +
622 (kDefaultTCPMSS * 2 * kNumberOfAcks);
623 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
625 LoseNPackets(1);
627 // We should now have fallen out of slow start with a reduced window.
628 expected_send_window *= kRenoBeta;
629 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
631 // No congestion window growth should occur in recovery phase, i.e., until the
632 // currently outstanding 20 packets are acked.
633 for (int i = 0; i < 10; ++i) {
634 // Send our full send window.
635 SendAvailableSendWindow();
636 EXPECT_TRUE(sender_->InRecovery());
637 AckNPackets(2);
638 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
640 EXPECT_FALSE(sender_->InRecovery());
642 // Out of recovery now. Congestion window should not grow during RTT.
643 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
644 // Send our full send window.
645 SendAvailableSendWindow();
646 AckNPackets(2);
647 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
650 // Next ack should cause congestion window to grow by 1MSS.
651 SendAvailableSendWindow();
652 AckNPackets(2);
653 expected_send_window += kDefaultTCPMSS;
654 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
657 TEST_F(TcpCubicSenderTest, BandwidthResumption) {
658 // Test that when provided with CachedNetworkParameters and opted in to the
659 // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
660 // appropriately.
662 // Set some common values.
663 CachedNetworkParameters cached_network_params;
664 const QuicPacketCount kNumberOfPackets = 123;
665 const int kBandwidthEstimateBytesPerSecond =
666 kNumberOfPackets * kMaxPacketSize;
667 cached_network_params.set_bandwidth_estimate_bytes_per_second(
668 kBandwidthEstimateBytesPerSecond);
669 cached_network_params.set_min_rtt_ms(1000);
671 // Make sure that a bandwidth estimate results in a changed CWND.
672 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
673 (kNumSecondsPerHour - 1));
674 sender_->ResumeConnectionState(cached_network_params, false);
675 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window());
677 // Resumed CWND is limited to be in a sensible range.
678 cached_network_params.set_bandwidth_estimate_bytes_per_second(
679 (kMaxCongestionWindow + 1) * kMaxPacketSize);
680 sender_->ResumeConnectionState(cached_network_params, false);
681 EXPECT_EQ(kMaxCongestionWindow, sender_->congestion_window());
683 cached_network_params.set_bandwidth_estimate_bytes_per_second(
684 (kMinCongestionWindowForBandwidthResumption - 1) * kMaxPacketSize);
685 sender_->ResumeConnectionState(cached_network_params, false);
686 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption,
687 sender_->congestion_window());
689 // Resume to the max value.
690 cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
691 (kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS);
692 sender_->ResumeConnectionState(cached_network_params, true);
693 EXPECT_EQ((kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS,
694 sender_->GetCongestionWindow());
697 TEST_F(TcpCubicSenderTest, PaceBelowCWND) {
698 QuicConfig config;
700 // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
701 // to 4 to be sent.
702 QuicTagVector options;
703 options.push_back(kMIN4);
704 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
705 sender_->SetFromConfig(config, Perspective::IS_SERVER);
706 sender_->OnRetransmissionTimeout(true);
707 EXPECT_EQ(1u, sender_->congestion_window());
708 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
709 HAS_RETRANSMITTABLE_DATA).IsZero());
710 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
711 HAS_RETRANSMITTABLE_DATA).IsZero());
712 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
713 HAS_RETRANSMITTABLE_DATA).IsZero());
714 EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
715 HAS_RETRANSMITTABLE_DATA).IsZero());
718 } // namespace test
719 } // namespace net