Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / net / quic / congestion_control / tcp_cubic_bytes_sender_test.cc
blobff30bb5a422a5ddcc0c1415bb6d2f384aba27a32
1 // Copyright (c) 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.
5 #include "net/quic/congestion_control/tcp_cubic_bytes_sender.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "net/quic/congestion_control/rtt_stats.h"
12 #include "net/quic/crypto/crypto_protocol.h"
13 #include "net/quic/proto/cached_network_parameters.pb.h"
14 #include "net/quic/quic_flags.h"
15 #include "net/quic/quic_protocol.h"
16 #include "net/quic/quic_utils.h"
17 #include "net/quic/test_tools/mock_clock.h"
18 #include "net/quic/test_tools/quic_config_peer.h"
19 #include "net/quic/test_tools/quic_test_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace net {
23 namespace test {
25 // TODO(ianswett): A number of theses tests were written with the assumption of
26 // an initial CWND of 10. They have carefully calculated values which should be
27 // updated to be based on kInitialCongestionWindowInsecure.
28 const uint32 kInitialCongestionWindowPackets = 10;
29 const uint32 kDefaultWindowTCP =
30 kInitialCongestionWindowPackets * kDefaultTCPMSS;
31 const float kRenoBeta = 0.7f; // Reno backoff factor.
33 class TcpCubicBytesSenderPeer : public TcpCubicBytesSender {
34 public:
35 TcpCubicBytesSenderPeer(const QuicClock* clock, bool reno)
36 : TcpCubicBytesSender(clock,
37 &rtt_stats_,
38 reno,
39 kInitialCongestionWindowPackets,
40 kMaxCongestionWindow,
41 &stats_) {}
43 const HybridSlowStart& hybrid_slow_start() const {
44 return hybrid_slow_start_;
47 float GetRenoBeta() const { return RenoBeta(); }
49 RttStats rtt_stats_;
50 QuicConnectionStats stats_;
53 class TcpCubicBytesSenderTest : public ::testing::Test {
54 protected:
55 TcpCubicBytesSenderTest()
56 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
57 sender_(new TcpCubicBytesSenderPeer(&clock_, true)),
58 packet_number_(1),
59 acked_packet_number_(0),
60 bytes_in_flight_(0) {
61 standard_packet_.bytes_sent = kDefaultTCPMSS;
64 int SendAvailableSendWindow() {
65 // Send as long as TimeUntilSend returns Zero.
66 int packets_sent = 0;
67 bool can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
68 HAS_RETRANSMITTABLE_DATA).IsZero();
69 while (can_send) {
70 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
71 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
72 ++packets_sent;
73 bytes_in_flight_ += kDefaultTCPMSS;
74 can_send = sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
75 HAS_RETRANSMITTABLE_DATA).IsZero();
77 return packets_sent;
80 // Normal is that TCP acks every other segment.
81 void AckNPackets(int n) {
82 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
83 QuicTime::Delta::Zero(), clock_.Now());
84 SendAlgorithmInterface::CongestionVector acked_packets;
85 SendAlgorithmInterface::CongestionVector lost_packets;
86 for (int i = 0; i < n; ++i) {
87 ++acked_packet_number_;
88 acked_packets.push_back(
89 std::make_pair(acked_packet_number_, standard_packet_));
91 sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
92 lost_packets);
93 bytes_in_flight_ -= n * kDefaultTCPMSS;
94 clock_.AdvanceTime(one_ms_);
97 void LoseNPackets(int n) {
98 SendAlgorithmInterface::CongestionVector acked_packets;
99 SendAlgorithmInterface::CongestionVector lost_packets;
100 for (int i = 0; i < n; ++i) {
101 ++acked_packet_number_;
102 lost_packets.push_back(
103 std::make_pair(acked_packet_number_, standard_packet_));
105 sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
106 lost_packets);
107 bytes_in_flight_ -= n * kDefaultTCPMSS;
110 // Does not increment acked_packet_number_.
111 void LosePacket(QuicPacketNumber packet_number) {
112 SendAlgorithmInterface::CongestionVector acked_packets;
113 SendAlgorithmInterface::CongestionVector lost_packets;
114 lost_packets.push_back(std::make_pair(packet_number, standard_packet_));
115 sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
116 lost_packets);
117 bytes_in_flight_ -= kDefaultTCPMSS;
120 const QuicTime::Delta one_ms_;
121 MockClock clock_;
122 scoped_ptr<TcpCubicBytesSenderPeer> sender_;
123 QuicPacketNumber packet_number_;
124 QuicPacketNumber acked_packet_number_;
125 QuicByteCount bytes_in_flight_;
126 TransmissionInfo standard_packet_;
129 TEST_F(TcpCubicBytesSenderTest, SimpleSender) {
130 // At startup make sure we are at the default.
131 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
132 // At startup make sure we can send.
133 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
134 HAS_RETRANSMITTABLE_DATA).IsZero());
135 // Make sure we can send.
136 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
137 HAS_RETRANSMITTABLE_DATA).IsZero());
138 // And that window is un-affected.
139 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
141 // Fill the send window with data, then verify that we can't send.
142 SendAvailableSendWindow();
143 EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
144 sender_->GetCongestionWindow(),
145 HAS_RETRANSMITTABLE_DATA).IsZero());
148 TEST_F(TcpCubicBytesSenderTest, ApplicationLimitedSlowStart) {
149 // Send exactly 10 packets and ensure the CWND ends at 14 packets.
150 const int kNumberOfAcks = 5;
151 // At startup make sure we can send.
152 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
153 HAS_RETRANSMITTABLE_DATA).IsZero());
154 // Make sure we can send.
155 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
156 HAS_RETRANSMITTABLE_DATA).IsZero());
158 SendAvailableSendWindow();
159 for (int i = 0; i < kNumberOfAcks; ++i) {
160 AckNPackets(2);
162 QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
163 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
164 // half the CWND.
165 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
168 TEST_F(TcpCubicBytesSenderTest, ExponentialSlowStart) {
169 const int kNumberOfAcks = 20;
170 // At startup make sure we can send.
171 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
172 HAS_RETRANSMITTABLE_DATA).IsZero());
173 EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
174 // Make sure we can send.
175 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0,
176 HAS_RETRANSMITTABLE_DATA).IsZero());
178 for (int i = 0; i < kNumberOfAcks; ++i) {
179 // Send our full send window.
180 SendAvailableSendWindow();
181 AckNPackets(2);
183 const QuicByteCount cwnd = sender_->GetCongestionWindow();
184 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
185 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
186 cwnd, sender_->rtt_stats_.smoothed_rtt()),
187 sender_->BandwidthEstimate());
190 TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLoss) {
191 sender_->SetNumEmulatedConnections(1);
192 const int kNumberOfAcks = 10;
193 for (int i = 0; i < kNumberOfAcks; ++i) {
194 // Send our full send window.
195 SendAvailableSendWindow();
196 AckNPackets(2);
198 SendAvailableSendWindow();
199 QuicByteCount expected_send_window =
200 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
201 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
203 // Lose a packet to exit slow start.
204 LoseNPackets(1);
205 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
207 // We should now have fallen out of slow start with a reduced window.
208 expected_send_window *= kRenoBeta;
209 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
211 // Recovery phase. We need to ack every packet in the recovery window before
212 // we exit recovery.
213 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
214 DVLOG(1) << "number_packets: " << number_of_packets_in_window;
215 AckNPackets(packets_in_recovery_window);
216 SendAvailableSendWindow();
217 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
219 // We need to ack an entire window before we increase CWND by 1.
220 AckNPackets(number_of_packets_in_window - 2);
221 SendAvailableSendWindow();
222 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
224 // Next ack should increase cwnd by 1.
225 AckNPackets(1);
226 expected_send_window += kDefaultTCPMSS;
227 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
229 // Now RTO and ensure slow start gets reset.
230 EXPECT_TRUE(sender_->hybrid_slow_start().started());
231 sender_->OnRetransmissionTimeout(true);
232 EXPECT_FALSE(sender_->hybrid_slow_start().started());
235 TEST_F(TcpCubicBytesSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
236 SendAvailableSendWindow();
237 LoseNPackets(kInitialCongestionWindowPackets - 1);
238 AckNPackets(1);
239 // PRR will allow 2 packets for every ack during recovery.
240 EXPECT_EQ(2, SendAvailableSendWindow());
241 // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
242 // PRR should now allow a packet to be sent, even though prr's state variables
243 // believe it has sent enough packets.
244 EXPECT_EQ(QuicTime::Delta::Zero(),
245 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA));
248 TEST_F(TcpCubicBytesSenderTest, SlowStartPacketLossPRR) {
249 sender_->SetNumEmulatedConnections(1);
250 // Test based on the first example in RFC6937.
251 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
252 const int kNumberOfAcks = 5;
253 for (int i = 0; i < kNumberOfAcks; ++i) {
254 // Send our full send window.
255 SendAvailableSendWindow();
256 AckNPackets(2);
258 SendAvailableSendWindow();
259 QuicByteCount expected_send_window =
260 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
261 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
263 LoseNPackets(1);
265 // We should now have fallen out of slow start with a reduced window.
266 size_t send_window_before_loss = expected_send_window;
267 expected_send_window *= kRenoBeta;
268 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
270 // Testing TCP proportional rate reduction.
271 // We should send packets paced over the received acks for the remaining
272 // outstanding packets. The number of packets before we exit recovery is the
273 // original CWND minus the packet that has been lost and the one which
274 // triggered the loss.
275 size_t remaining_packets_in_recovery =
276 send_window_before_loss / kDefaultTCPMSS - 2;
278 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
279 AckNPackets(1);
280 SendAvailableSendWindow();
281 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
284 // We need to ack another window before we increase CWND by 1.
285 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
286 for (size_t i = 0; i < number_of_packets_in_window; ++i) {
287 AckNPackets(1);
288 EXPECT_EQ(1, SendAvailableSendWindow());
289 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
292 AckNPackets(1);
293 expected_send_window += kDefaultTCPMSS;
294 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
297 TEST_F(TcpCubicBytesSenderTest, SlowStartBurstPacketLossPRR) {
298 sender_->SetNumEmulatedConnections(1);
299 // Test based on the second example in RFC6937, though we also implement
300 // forward acknowledgements, so the first two incoming acks will trigger
301 // PRR immediately.
302 // Ack 20 packets in 10 acks to raise the CWND to 30.
303 const int kNumberOfAcks = 10;
304 for (int i = 0; i < kNumberOfAcks; ++i) {
305 // Send our full send window.
306 SendAvailableSendWindow();
307 AckNPackets(2);
309 SendAvailableSendWindow();
310 QuicByteCount expected_send_window =
311 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
312 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
314 // Lose one more than the congestion window reduction, so that after loss,
315 // bytes_in_flight is lesser than the congestion window.
316 size_t send_window_after_loss = kRenoBeta * expected_send_window;
317 size_t num_packets_to_lose =
318 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
319 LoseNPackets(num_packets_to_lose);
320 // Immediately after the loss, ensure at least one packet can be sent.
321 // Losses without subsequent acks can occur with timer based loss detection.
322 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_,
323 HAS_RETRANSMITTABLE_DATA).IsZero());
324 AckNPackets(1);
326 // We should now have fallen out of slow start with a reduced window.
327 expected_send_window *= kRenoBeta;
328 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
330 // Only 2 packets should be allowed to be sent, per PRR-SSRB.
331 EXPECT_EQ(2, SendAvailableSendWindow());
333 // Ack the next packet, which triggers another loss.
334 LoseNPackets(1);
335 AckNPackets(1);
337 // Send 2 packets to simulate PRR-SSRB.
338 EXPECT_EQ(2, SendAvailableSendWindow());
340 // Ack the next packet, which triggers another loss.
341 LoseNPackets(1);
342 AckNPackets(1);
344 // Send 2 packets to simulate PRR-SSRB.
345 EXPECT_EQ(2, SendAvailableSendWindow());
347 // Exit recovery and return to sending at the new rate.
348 for (int i = 0; i < kNumberOfAcks; ++i) {
349 AckNPackets(1);
350 EXPECT_EQ(1, SendAvailableSendWindow());
354 TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindow) {
355 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
356 // Expect the window to decrease to the minimum once the RTO fires and slow
357 // start threshold to be set to 1/2 of the CWND.
358 sender_->OnRetransmissionTimeout(true);
359 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
360 EXPECT_EQ(5u * kDefaultTCPMSS, sender_->GetSlowStartThreshold());
363 TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindowNoRetransmission) {
364 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
366 // Expect the window to remain unchanged if the RTO fires but no packets are
367 // retransmitted.
368 sender_->OnRetransmissionTimeout(false);
369 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
372 TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) {
373 const int64 kRttMs = 10;
374 const int64 kDeviationMs = 3;
375 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
377 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
378 QuicTime::Delta::Zero(), clock_.Now());
380 // Initial value is to set the median deviation to half of the initial rtt,
381 // the median in then multiplied by a factor of 4 and finally the smoothed rtt
382 // is added which is the initial rtt.
383 QuicTime::Delta expected_delay =
384 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
385 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
387 for (int i = 0; i < 100; ++i) {
388 // Run to make sure that we converge.
389 sender_->rtt_stats_.UpdateRtt(
390 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
391 QuicTime::Delta::Zero(), clock_.Now());
392 sender_->rtt_stats_.UpdateRtt(
393 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
394 QuicTime::Delta::Zero(), clock_.Now());
396 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
398 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
399 EXPECT_NEAR(expected_delay.ToMilliseconds(),
400 sender_->RetransmissionDelay().ToMilliseconds(), 1);
401 EXPECT_EQ(
402 static_cast<int64>(sender_->GetCongestionWindow() * kNumMicrosPerSecond /
403 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
404 sender_->BandwidthEstimate().ToBytesPerSecond());
407 TEST_F(TcpCubicBytesSenderTest, TcpCubicResetEpochOnQuiescence) {
408 ValueRestore<bool> old_flag(&FLAGS_reset_cubic_epoch_when_app_limited, true);
409 const int kMaxCongestionWindow = 50;
410 const QuicByteCount kMaxCongestionWindowBytes =
411 kMaxCongestionWindow * kDefaultTCPMSS;
412 int num_sent = SendAvailableSendWindow();
414 // Make sure we fall out of slow start.
415 QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
416 LoseNPackets(1);
417 EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
419 // Ack the rest of the outstanding packets to get out of recovery.
420 for (int i = 1; i < num_sent; ++i) {
421 AckNPackets(1);
423 EXPECT_EQ(0u, bytes_in_flight_);
425 // Send a new window of data and ack all; cubic growth should occur.
426 saved_cwnd = sender_->GetCongestionWindow();
427 num_sent = SendAvailableSendWindow();
428 for (int i = 0; i < num_sent; ++i) {
429 AckNPackets(1);
431 EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
432 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
433 EXPECT_EQ(0u, bytes_in_flight_);
435 // Quiescent time of 100 seconds
436 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
438 // Send new window of data and ack one packet. Cubic epoch should have
439 // been reset; ensure cwnd increase is not dramatic.
440 saved_cwnd = sender_->GetCongestionWindow();
441 SendAvailableSendWindow();
442 AckNPackets(1);
443 EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
444 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
447 TEST_F(TcpCubicBytesSenderTest, MultipleLossesInOneWindow) {
448 SendAvailableSendWindow();
449 const QuicByteCount initial_window = sender_->GetCongestionWindow();
450 LosePacket(acked_packet_number_ + 1);
451 const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
452 EXPECT_GT(initial_window, post_loss_window);
453 LosePacket(acked_packet_number_ + 3);
454 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
455 LosePacket(packet_number_ - 1);
456 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
458 // Lose a later packet and ensure the window decreases.
459 LosePacket(packet_number_);
460 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
463 TEST_F(TcpCubicBytesSenderTest, DontTrackAckPackets) {
464 // Send a packet with no retransmittable data, and ensure it's not tracked.
465 EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
466 packet_number_++, kDefaultTCPMSS,
467 NO_RETRANSMITTABLE_DATA));
469 // Send a data packet with retransmittable data, and ensure it is tracked.
470 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
471 packet_number_++, kDefaultTCPMSS,
472 HAS_RETRANSMITTABLE_DATA));
475 TEST_F(TcpCubicBytesSenderTest, ConfigureMaxInitialWindow) {
476 QuicConfig config;
478 // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
479 QuicTagVector options;
480 options.push_back(kIW10);
481 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
482 sender_->SetFromConfig(config, Perspective::IS_SERVER);
483 EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
486 TEST_F(TcpCubicBytesSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
487 sender_->SetNumEmulatedConnections(2);
488 // Ack 10 packets in 5 acks to raise the CWND to 20.
489 const int kNumberOfAcks = 5;
490 for (int i = 0; i < kNumberOfAcks; ++i) {
491 // Send our full send window.
492 SendAvailableSendWindow();
493 AckNPackets(2);
495 SendAvailableSendWindow();
496 QuicByteCount expected_send_window =
497 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
498 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
500 LoseNPackets(1);
502 // We should now have fallen out of slow start with a reduced window.
503 expected_send_window = expected_send_window * sender_->GetRenoBeta();
504 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
506 // No congestion window growth should occur in recovery phase, i.e., until the
507 // currently outstanding 20 packets are acked.
508 for (int i = 0; i < 10; ++i) {
509 // Send our full send window.
510 SendAvailableSendWindow();
511 EXPECT_TRUE(sender_->InRecovery());
512 AckNPackets(2);
513 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
515 EXPECT_FALSE(sender_->InRecovery());
517 // Out of recovery now. Congestion window should not grow for half an RTT.
518 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
519 SendAvailableSendWindow();
520 AckNPackets(packets_in_send_window / 2 - 2);
521 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
523 // Next ack should increase congestion window by 1MSS.
524 SendAvailableSendWindow();
525 AckNPackets(2);
526 expected_send_window += kDefaultTCPMSS;
527 packets_in_send_window += 1;
528 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
530 // Congestion window should remain steady again for half an RTT.
531 SendAvailableSendWindow();
532 AckNPackets(packets_in_send_window / 2 - 1);
533 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
535 // Next ack should cause congestion window to grow by 1MSS.
536 SendAvailableSendWindow();
537 AckNPackets(2);
538 expected_send_window += kDefaultTCPMSS;
539 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
542 TEST_F(TcpCubicBytesSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
543 sender_->SetNumEmulatedConnections(1);
544 // Ack 10 packets in 5 acks to raise the CWND to 20.
545 const int kNumberOfAcks = 5;
546 for (int i = 0; i < kNumberOfAcks; ++i) {
547 // Send our full send window.
548 SendAvailableSendWindow();
549 AckNPackets(2);
551 SendAvailableSendWindow();
552 QuicByteCount expected_send_window =
553 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
554 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
556 LoseNPackets(1);
558 // We should now have fallen out of slow start with a reduced window.
559 expected_send_window *= kRenoBeta;
560 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
562 // No congestion window growth should occur in recovery phase, i.e., until the
563 // currently outstanding 20 packets are acked.
564 for (int i = 0; i < 10; ++i) {
565 // Send our full send window.
566 SendAvailableSendWindow();
567 EXPECT_TRUE(sender_->InRecovery());
568 AckNPackets(2);
569 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
571 EXPECT_FALSE(sender_->InRecovery());
573 // Out of recovery now. Congestion window should not grow during RTT.
574 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
575 // Send our full send window.
576 SendAvailableSendWindow();
577 AckNPackets(2);
578 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
581 // Next ack should cause congestion window to grow by 1MSS.
582 SendAvailableSendWindow();
583 AckNPackets(2);
584 expected_send_window += kDefaultTCPMSS;
585 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
588 TEST_F(TcpCubicBytesSenderTest, BandwidthResumption) {
589 // Test that when provided with CachedNetworkParameters and opted in to the
590 // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
591 // appropriately.
593 // Set some common values.
594 CachedNetworkParameters cached_network_params;
595 const QuicPacketCount kNumberOfPackets = 123;
596 const int kBandwidthEstimateBytesPerSecond =
597 kNumberOfPackets * kDefaultTCPMSS;
598 cached_network_params.set_bandwidth_estimate_bytes_per_second(
599 kBandwidthEstimateBytesPerSecond);
600 cached_network_params.set_min_rtt_ms(1000);
602 // Make sure that a bandwidth estimate results in a changed CWND.
603 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
604 (kNumSecondsPerHour - 1));
605 sender_->ResumeConnectionState(cached_network_params, false);
606 EXPECT_EQ(kNumberOfPackets * kDefaultTCPMSS, sender_->GetCongestionWindow());
608 // Resumed CWND is limited to be in a sensible range.
609 cached_network_params.set_bandwidth_estimate_bytes_per_second(
610 (kMaxCongestionWindow + 1) * kDefaultTCPMSS);
611 sender_->ResumeConnectionState(cached_network_params, false);
612 EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS,
613 sender_->GetCongestionWindow());
615 cached_network_params.set_bandwidth_estimate_bytes_per_second(
616 (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS);
617 sender_->ResumeConnectionState(cached_network_params, false);
618 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption * kDefaultTCPMSS,
619 sender_->GetCongestionWindow());
621 // Resume to the max value.
622 cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
623 (kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS);
624 sender_->ResumeConnectionState(cached_network_params, true);
625 EXPECT_EQ((kMinCongestionWindowForBandwidthResumption + 10) * kDefaultTCPMSS,
626 sender_->GetCongestionWindow());
629 TEST_F(TcpCubicBytesSenderTest, PaceBelowCWND) {
630 QuicConfig config;
632 // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
633 // to 4 to be sent.
634 QuicTagVector options;
635 options.push_back(kMIN4);
636 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
637 sender_->SetFromConfig(config, Perspective::IS_SERVER);
638 sender_->OnRetransmissionTimeout(true);
639 EXPECT_EQ(kDefaultTCPMSS, sender_->GetCongestionWindow());
640 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS,
641 HAS_RETRANSMITTABLE_DATA).IsZero());
642 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS,
643 HAS_RETRANSMITTABLE_DATA).IsZero());
644 EXPECT_TRUE(sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS,
645 HAS_RETRANSMITTABLE_DATA).IsZero());
646 EXPECT_FALSE(sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS,
647 HAS_RETRANSMITTABLE_DATA).IsZero());
650 } // namespace test
651 } // namespace net