ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / net / quic / congestion_control / tcp_cubic_sender_test.cc
blobab5fcdbc36b53660b760289d383ad6cb17d5aeba
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/quic_protocol.h"
13 #include "net/quic/quic_utils.h"
14 #include "net/quic/test_tools/mock_clock.h"
15 #include "net/quic/test_tools/quic_config_peer.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using std::min;
20 namespace net {
21 namespace test {
23 // TODO(ianswett): A number of theses tests were written with the assumption of
24 // an initial CWND of 10. They have carefully calculated values which should be
25 // updated to be based on kInitialCongestionWindowInsecure.
26 const uint32 kInitialCongestionWindowPackets = 10;
27 const uint32 kDefaultWindowTCP =
28 kInitialCongestionWindowPackets * kDefaultTCPMSS;
29 const float kRenoBeta = 0.7f; // Reno backoff factor.
31 class TcpCubicSenderPeer : public TcpCubicSender {
32 public:
33 TcpCubicSenderPeer(const QuicClock* clock, bool reno)
34 : TcpCubicSender(clock,
35 &rtt_stats_,
36 reno,
37 kInitialCongestionWindowPackets,
38 &stats_) {}
40 QuicPacketCount congestion_window() {
41 return congestion_window_;
44 QuicPacketCount slowstart_threshold() {
45 return slowstart_threshold_;
48 const HybridSlowStart& hybrid_slow_start() const {
49 return hybrid_slow_start_;
52 float GetRenoBeta() const {
53 return RenoBeta();
56 RttStats rtt_stats_;
57 QuicConnectionStats stats_;
60 class TcpCubicSenderTest : public ::testing::Test {
61 protected:
62 TcpCubicSenderTest()
63 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
64 sender_(new TcpCubicSenderPeer(&clock_, true)),
65 sequence_number_(1),
66 acked_sequence_number_(0),
67 bytes_in_flight_(0) {
68 standard_packet_.bytes_sent = kDefaultTCPMSS;
71 int SendAvailableSendWindow() {
72 // Send as long as TimeUntilSend returns Zero.
73 int packets_sent = 0;
74 bool can_send = sender_->TimeUntilSend(
75 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
76 while (can_send) {
77 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++,
78 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
79 ++packets_sent;
80 bytes_in_flight_ += kDefaultTCPMSS;
81 can_send = sender_->TimeUntilSend(
82 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
84 return packets_sent;
87 // Normal is that TCP acks every other segment.
88 void AckNPackets(int n) {
89 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
90 QuicTime::Delta::Zero(),
91 clock_.Now());
92 SendAlgorithmInterface::CongestionVector acked_packets;
93 SendAlgorithmInterface::CongestionVector lost_packets;
94 for (int i = 0; i < n; ++i) {
95 ++acked_sequence_number_;
96 acked_packets.push_back(
97 std::make_pair(acked_sequence_number_, standard_packet_));
99 sender_->OnCongestionEvent(
100 true, bytes_in_flight_, acked_packets, lost_packets);
101 bytes_in_flight_ -= n * kDefaultTCPMSS;
102 clock_.AdvanceTime(one_ms_);
105 void LoseNPackets(int n) {
106 SendAlgorithmInterface::CongestionVector acked_packets;
107 SendAlgorithmInterface::CongestionVector lost_packets;
108 for (int i = 0; i < n; ++i) {
109 ++acked_sequence_number_;
110 lost_packets.push_back(
111 std::make_pair(acked_sequence_number_, standard_packet_));
113 sender_->OnCongestionEvent(
114 false, bytes_in_flight_, acked_packets, lost_packets);
115 bytes_in_flight_ -= n * kDefaultTCPMSS;
118 // Does not increment acked_sequence_number_.
119 void LosePacket(QuicPacketSequenceNumber sequence_number) {
120 SendAlgorithmInterface::CongestionVector acked_packets;
121 SendAlgorithmInterface::CongestionVector lost_packets;
122 lost_packets.push_back(std::make_pair(sequence_number, standard_packet_));
123 sender_->OnCongestionEvent(
124 false, bytes_in_flight_, acked_packets, lost_packets);
125 bytes_in_flight_ -= kDefaultTCPMSS;
128 const QuicTime::Delta one_ms_;
129 MockClock clock_;
130 scoped_ptr<TcpCubicSenderPeer> sender_;
131 QuicPacketSequenceNumber sequence_number_;
132 QuicPacketSequenceNumber acked_sequence_number_;
133 QuicByteCount bytes_in_flight_;
134 TransmissionInfo standard_packet_;
137 TEST_F(TcpCubicSenderTest, SimpleSender) {
138 // At startup make sure we are at the default.
139 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
140 // At startup make sure we can send.
141 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
143 HAS_RETRANSMITTABLE_DATA).IsZero());
144 // Make sure we can send.
145 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
147 HAS_RETRANSMITTABLE_DATA).IsZero());
148 // And that window is un-affected.
149 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
151 // Fill the send window with data, then verify that we can't send.
152 SendAvailableSendWindow();
153 EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
154 sender_->GetCongestionWindow(),
155 HAS_RETRANSMITTABLE_DATA).IsZero());
158 TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
159 // Send exactly 10 packets and ensure the CWND ends at 14 packets.
160 const int kNumberOfAcks = 5;
161 // At startup make sure we can send.
162 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
164 HAS_RETRANSMITTABLE_DATA).IsZero());
165 // Make sure we can send.
166 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
168 HAS_RETRANSMITTABLE_DATA).IsZero());
170 SendAvailableSendWindow();
171 for (int i = 0; i < kNumberOfAcks; ++i) {
172 AckNPackets(2);
174 QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
175 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
176 // half the CWND.
177 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
178 bytes_to_send);
181 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
182 const int kNumberOfAcks = 20;
183 // At startup make sure we can send.
184 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
186 HAS_RETRANSMITTABLE_DATA).IsZero());
187 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate());
188 EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
189 // Make sure we can send.
190 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
192 HAS_RETRANSMITTABLE_DATA).IsZero());
194 for (int i = 0; i < kNumberOfAcks; ++i) {
195 // Send our full send window.
196 SendAvailableSendWindow();
197 AckNPackets(2);
199 const QuicByteCount cwnd = sender_->GetCongestionWindow();
200 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
201 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate());
202 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
203 cwnd, sender_->rtt_stats_.smoothed_rtt()),
204 sender_->BandwidthEstimate());
207 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) {
208 sender_->SetNumEmulatedConnections(1);
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 for (int i = 0; i < kNumberOfAcks; ++i) {
217 // Send our full send window.
218 SendAvailableSendWindow();
219 AckNPackets(2);
221 QuicByteCount expected_send_window =
222 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
223 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
225 // We should now have fallen out of slow start.
226 // Testing Reno phase.
227 // We should need 140(65*2+10) ACK:ed packets before increasing window by
228 // one.
229 for (int i = 0; i < 69; ++i) {
230 SendAvailableSendWindow();
231 AckNPackets(2);
232 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
234 SendAvailableSendWindow();
235 AckNPackets(2);
236 QuicByteCount expected_ss_tresh = expected_send_window;
237 expected_send_window += kDefaultTCPMSS;
238 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
239 EXPECT_EQ(expected_ss_tresh, sender_->GetSlowStartThreshold());
240 EXPECT_EQ(140u, sender_->slowstart_threshold());
242 // Now RTO and ensure slow start gets reset.
243 EXPECT_TRUE(sender_->hybrid_slow_start().started());
244 sender_->OnRetransmissionTimeout(true);
245 EXPECT_FALSE(sender_->hybrid_slow_start().started());
246 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
247 EXPECT_EQ(expected_send_window / 2 / kDefaultTCPMSS,
248 sender_->slowstart_threshold());
251 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
252 sender_->SetNumEmulatedConnections(1);
253 const int kNumberOfAcks = 10;
254 for (int i = 0; i < kNumberOfAcks; ++i) {
255 // Send our full send window.
256 SendAvailableSendWindow();
257 AckNPackets(2);
259 SendAvailableSendWindow();
260 QuicByteCount expected_send_window = kDefaultWindowTCP +
261 (kDefaultTCPMSS * 2 * kNumberOfAcks);
262 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
264 // Lose a packet to exit slow start.
265 LoseNPackets(1);
266 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
268 // We should now have fallen out of slow start with a reduced window.
269 expected_send_window *= kRenoBeta;
270 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
272 // Recovery phase. We need to ack every packet in the recovery window before
273 // we exit recovery.
274 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
275 DVLOG(1) << "number_packets: " << number_of_packets_in_window;
276 AckNPackets(packets_in_recovery_window);
277 SendAvailableSendWindow();
278 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
280 // We need to ack an entire window before we increase CWND by 1.
281 AckNPackets(number_of_packets_in_window - 2);
282 SendAvailableSendWindow();
283 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
285 // Next ack should increase cwnd by 1.
286 AckNPackets(1);
287 expected_send_window += kDefaultTCPMSS;
288 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
290 // Now RTO and ensure slow start gets reset.
291 EXPECT_TRUE(sender_->hybrid_slow_start().started());
292 sender_->OnRetransmissionTimeout(true);
293 EXPECT_FALSE(sender_->hybrid_slow_start().started());
296 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
297 SendAvailableSendWindow();
298 LoseNPackets(kInitialCongestionWindowPackets - 1);
299 AckNPackets(1);
300 // PRR will allow 2 packets for every ack during recovery.
301 EXPECT_EQ(2, SendAvailableSendWindow());
302 // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
303 // PRR should now allow a packet to be sent, even though prr's state
304 // variables believe it has sent enough packets.
305 EXPECT_EQ(QuicTime::Delta::Zero(),
306 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA));
309 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
310 sender_->SetNumEmulatedConnections(1);
311 // Test based on the first example in RFC6937.
312 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
313 const int kNumberOfAcks = 5;
314 for (int i = 0; i < kNumberOfAcks; ++i) {
315 // Send our full send window.
316 SendAvailableSendWindow();
317 AckNPackets(2);
319 SendAvailableSendWindow();
320 QuicByteCount expected_send_window = kDefaultWindowTCP +
321 (kDefaultTCPMSS * 2 * kNumberOfAcks);
322 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
324 LoseNPackets(1);
326 // We should now have fallen out of slow start with a reduced window.
327 size_t send_window_before_loss = expected_send_window;
328 expected_send_window *= kRenoBeta;
329 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
331 // Testing TCP proportional rate reduction.
332 // We should send packets paced over the received acks for the remaining
333 // outstanding packets. The number of packets before we exit recovery is the
334 // original CWND minus the packet that has been lost and the one which
335 // triggered the loss.
336 size_t remaining_packets_in_recovery =
337 send_window_before_loss / kDefaultTCPMSS - 2;
339 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
340 AckNPackets(1);
341 SendAvailableSendWindow();
342 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
345 // We need to ack another window before we increase CWND by 1.
346 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
347 for (size_t i = 0; i < number_of_packets_in_window; ++i) {
348 AckNPackets(1);
349 EXPECT_EQ(1, SendAvailableSendWindow());
350 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
353 AckNPackets(1);
354 expected_send_window += kDefaultTCPMSS;
355 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
358 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
359 sender_->SetNumEmulatedConnections(1);
360 // Test based on the second example in RFC6937, though we also implement
361 // forward acknowledgements, so the first two incoming acks will trigger
362 // PRR immediately.
363 // Ack 20 packets in 10 acks to raise the CWND to 30.
364 const int kNumberOfAcks = 10;
365 for (int i = 0; i < kNumberOfAcks; ++i) {
366 // Send our full send window.
367 SendAvailableSendWindow();
368 AckNPackets(2);
370 SendAvailableSendWindow();
371 QuicByteCount expected_send_window = kDefaultWindowTCP +
372 (kDefaultTCPMSS * 2 * kNumberOfAcks);
373 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
375 // Lose one more than the congestion window reduction, so that after loss,
376 // bytes_in_flight is lesser than the congestion window.
377 size_t send_window_after_loss = kRenoBeta * expected_send_window;
378 size_t num_packets_to_lose =
379 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
380 LoseNPackets(num_packets_to_lose);
381 // Immediately after the loss, ensure at least one packet can be sent.
382 // Losses without subsequent acks can occur with timer based loss detection.
383 EXPECT_TRUE(sender_->TimeUntilSend(
384 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
385 AckNPackets(1);
387 // We should now have fallen out of slow start with a reduced window.
388 expected_send_window *= kRenoBeta;
389 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
391 // Only 2 packets should be allowed to be sent, per PRR-SSRB
392 EXPECT_EQ(2, SendAvailableSendWindow());
394 // Ack the next packet, which triggers another loss.
395 LoseNPackets(1);
396 AckNPackets(1);
398 // Send 2 packets to simulate PRR-SSRB.
399 EXPECT_EQ(2, SendAvailableSendWindow());
401 // Ack the next packet, which triggers another loss.
402 LoseNPackets(1);
403 AckNPackets(1);
405 // Send 2 packets to simulate PRR-SSRB.
406 EXPECT_EQ(2, SendAvailableSendWindow());
408 // Exit recovery and return to sending at the new rate.
409 for (int i = 0; i < kNumberOfAcks; ++i) {
410 AckNPackets(1);
411 EXPECT_EQ(1, SendAvailableSendWindow());
415 TEST_F(TcpCubicSenderTest, RTOCongestionWindow) {
416 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
417 // Expect the window to decrease to the minimum once the RTO fires
418 // and slow start threshold to be set to 1/2 of the CWND.
419 sender_->OnRetransmissionTimeout(true);
420 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
421 EXPECT_EQ(5u, sender_->slowstart_threshold());
424 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
425 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
427 // Expect the window to remain unchanged if the RTO fires but no
428 // packets are retransmitted.
429 sender_->OnRetransmissionTimeout(false);
430 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
433 TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
434 const int64 kRttMs = 10;
435 const int64 kDeviationMs = 3;
436 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
438 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
439 QuicTime::Delta::Zero(), clock_.Now());
441 // Initial value is to set the median deviation to half of the initial
442 // rtt, the median in then multiplied by a factor of 4 and finally the
443 // smoothed rtt is added which is the initial rtt.
444 QuicTime::Delta expected_delay =
445 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
446 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
448 for (int i = 0; i < 100; ++i) {
449 // Run to make sure that we converge.
450 sender_->rtt_stats_.UpdateRtt(
451 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
452 QuicTime::Delta::Zero(), clock_.Now());
453 sender_->rtt_stats_.UpdateRtt(
454 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
455 QuicTime::Delta::Zero(), clock_.Now());
457 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
459 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
460 EXPECT_NEAR(expected_delay.ToMilliseconds(),
461 sender_->RetransmissionDelay().ToMilliseconds(),
463 EXPECT_EQ(static_cast<int64>(
464 sender_->GetCongestionWindow() * kNumMicrosPerSecond /
465 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
466 sender_->BandwidthEstimate().ToBytesPerSecond());
469 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
470 SendAvailableSendWindow();
471 const QuicByteCount initial_window = sender_->GetCongestionWindow();
472 LosePacket(acked_sequence_number_ + 1);
473 const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
474 EXPECT_GT(initial_window, post_loss_window);
475 LosePacket(acked_sequence_number_ + 3);
476 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
477 LosePacket(sequence_number_ - 1);
478 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
480 // Lose a later packet and ensure the window decreases.
481 LosePacket(sequence_number_);
482 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
485 TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
486 // Send a packet with no retransmittable data, and ensure it's not tracked.
487 EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
488 sequence_number_++, kDefaultTCPMSS,
489 NO_RETRANSMITTABLE_DATA));
491 // Send a data packet with retransmittable data, and ensure it is tracked.
492 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
493 sequence_number_++, kDefaultTCPMSS,
494 HAS_RETRANSMITTABLE_DATA));
497 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) {
498 QuicConfig config;
500 // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
501 QuicTagVector options;
502 options.push_back(kIW10);
503 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
504 sender_->SetFromConfig(config,
505 /* is_server= */ true,
506 /* using_pacing= */ false);
507 EXPECT_EQ(10u, sender_->congestion_window());
510 TEST_F(TcpCubicSenderTest, DisableAckTrainDetectionWithPacing) {
511 EXPECT_TRUE(sender_->hybrid_slow_start().ack_train_detection());
513 QuicConfig config;
514 sender_->SetFromConfig(config,
515 /* is_server= */ true,
516 /* using_pacing= */ true);
517 EXPECT_FALSE(sender_->hybrid_slow_start().ack_train_detection());
520 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
521 sender_->SetNumEmulatedConnections(2);
522 // Ack 10 packets in 5 acks to raise the CWND to 20.
523 const int kNumberOfAcks = 5;
524 for (int i = 0; i < kNumberOfAcks; ++i) {
525 // Send our full send window.
526 SendAvailableSendWindow();
527 AckNPackets(2);
529 SendAvailableSendWindow();
530 QuicByteCount expected_send_window = kDefaultWindowTCP +
531 (kDefaultTCPMSS * 2 * kNumberOfAcks);
532 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
534 LoseNPackets(1);
536 // We should now have fallen out of slow start with a reduced window.
537 expected_send_window = expected_send_window * sender_->GetRenoBeta();
538 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
540 // No congestion window growth should occur in recovery phase, i.e., until the
541 // currently outstanding 20 packets are acked.
542 for (int i = 0; i < 10; ++i) {
543 // Send our full send window.
544 SendAvailableSendWindow();
545 EXPECT_TRUE(sender_->InRecovery());
546 AckNPackets(2);
547 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
549 EXPECT_FALSE(sender_->InRecovery());
551 // Out of recovery now. Congestion window should not grow for half an RTT.
552 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
553 SendAvailableSendWindow();
554 AckNPackets(packets_in_send_window / 2 - 2);
555 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
557 // Next ack should increase congestion window by 1MSS.
558 SendAvailableSendWindow();
559 AckNPackets(2);
560 expected_send_window += kDefaultTCPMSS;
561 packets_in_send_window += 1;
562 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
564 // Congestion window should remain steady again for half an RTT.
565 SendAvailableSendWindow();
566 AckNPackets(packets_in_send_window / 2 - 1);
567 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
569 // Next ack should cause congestion window to grow by 1MSS.
570 SendAvailableSendWindow();
571 AckNPackets(2);
572 expected_send_window += kDefaultTCPMSS;
573 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
576 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
577 sender_->SetNumEmulatedConnections(1);
578 // Ack 10 packets in 5 acks to raise the CWND to 20.
579 const int kNumberOfAcks = 5;
580 for (int i = 0; i < kNumberOfAcks; ++i) {
581 // Send our full send window.
582 SendAvailableSendWindow();
583 AckNPackets(2);
585 SendAvailableSendWindow();
586 QuicByteCount expected_send_window = kDefaultWindowTCP +
587 (kDefaultTCPMSS * 2 * kNumberOfAcks);
588 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
590 LoseNPackets(1);
592 // We should now have fallen out of slow start with a reduced window.
593 expected_send_window *= kRenoBeta;
594 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
596 // No congestion window growth should occur in recovery phase, i.e., until the
597 // currently outstanding 20 packets are acked.
598 for (int i = 0; i < 10; ++i) {
599 // Send our full send window.
600 SendAvailableSendWindow();
601 EXPECT_TRUE(sender_->InRecovery());
602 AckNPackets(2);
603 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
605 EXPECT_FALSE(sender_->InRecovery());
607 // Out of recovery now. Congestion window should not grow during RTT.
608 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
609 // Send our full send window.
610 SendAvailableSendWindow();
611 AckNPackets(2);
612 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
615 // Next ack should cause congestion window to grow by 1MSS.
616 SendAvailableSendWindow();
617 AckNPackets(2);
618 expected_send_window += kDefaultTCPMSS;
619 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
622 TEST_F(TcpCubicSenderTest, BandwidthResumption) {
623 // Test that when provided with CachedNetworkParameters and opted in to the
624 // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
625 // appropriately.
627 // Set some common values.
628 CachedNetworkParameters cached_network_params;
629 const QuicPacketCount kNumberOfPackets = 123;
630 const int kBandwidthEstimateBytesPerSecond =
631 kNumberOfPackets * kMaxPacketSize;
632 cached_network_params.set_bandwidth_estimate_bytes_per_second(
633 kBandwidthEstimateBytesPerSecond);
634 cached_network_params.set_min_rtt_ms(1000);
636 // Ensure that an old estimate is not used for bandwidth resumption.
637 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
638 (kNumSecondsPerHour + 1));
639 EXPECT_FALSE(sender_->ResumeConnectionState(cached_network_params));
640 EXPECT_EQ(10u, sender_->congestion_window());
642 // If the estimate is new enough, make sure it is used.
643 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
644 (kNumSecondsPerHour - 1));
645 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params));
646 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window());
648 // Resumed CWND is limited to be in a sensible range.
649 cached_network_params.set_bandwidth_estimate_bytes_per_second(
650 (kMaxCongestionWindowForBandwidthResumption + 1) * kMaxPacketSize);
651 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params));
652 EXPECT_EQ(kMaxCongestionWindowForBandwidthResumption,
653 sender_->congestion_window());
655 cached_network_params.set_bandwidth_estimate_bytes_per_second(
656 (kMinCongestionWindowForBandwidthResumption - 1) * kMaxPacketSize);
657 EXPECT_TRUE(sender_->ResumeConnectionState(cached_network_params));
658 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption,
659 sender_->congestion_window());
662 } // namespace test
663 } // namespace net