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. 4 5 #include <algorithm> 6 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/crypto/crypto_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" 17 18 using std::make_pair; 19 using std::min; 20 21 namespace net { 22 namespace test { 23 24 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; 25 26 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. 27 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; 28 29 class TcpCubicSenderPeer : public TcpCubicSender { 30 public: 31 TcpCubicSenderPeer(const QuicClock* clock, 32 bool reno, 33 QuicTcpCongestionWindow max_tcp_congestion_window) 34 : TcpCubicSender( 35 clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) { 36 } 37 38 QuicTcpCongestionWindow congestion_window() { 39 return congestion_window_; 40 } 41 42 QuicTcpCongestionWindow slowstart_threshold() { 43 return slowstart_threshold_; 44 } 45 46 const HybridSlowStart& hybrid_slow_start() const { 47 return hybrid_slow_start_; 48 } 49 50 RttStats rtt_stats_; 51 QuicConnectionStats stats_; 52 53 using TcpCubicSender::SendWindow; 54 }; 55 56 class TcpCubicSenderTest : public ::testing::Test { 57 protected: 58 TcpCubicSenderTest() 59 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), 60 sender_(new TcpCubicSenderPeer(&clock_, true, 61 kDefaultMaxCongestionWindowTCP)), 62 receiver_(new TcpReceiver()), 63 sequence_number_(1), 64 acked_sequence_number_(0), 65 bytes_in_flight_(0) { 66 standard_packet_.bytes_sent = kDefaultTCPMSS; 67 } 68 69 int SendAvailableSendWindow() { 70 // Send as long as TimeUntilSend returns Zero. 71 int packets_sent = 0; 72 bool can_send = sender_->TimeUntilSend( 73 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero(); 74 while (can_send) { 75 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++, 76 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA); 77 ++packets_sent; 78 bytes_in_flight_ += kDefaultTCPMSS; 79 can_send = sender_->TimeUntilSend( 80 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero(); 81 } 82 return packets_sent; 83 } 84 85 // Normal is that TCP acks every other segment. 86 void AckNPackets(int n) { 87 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60), 88 QuicTime::Delta::Zero(), 89 clock_.Now()); 90 SendAlgorithmInterface::CongestionVector acked_packets; 91 SendAlgorithmInterface::CongestionVector lost_packets; 92 for (int i = 0; i < n; ++i) { 93 ++acked_sequence_number_; 94 acked_packets.push_back( 95 make_pair(acked_sequence_number_, standard_packet_)); 96 } 97 sender_->OnCongestionEvent( 98 true, bytes_in_flight_, acked_packets, lost_packets); 99 bytes_in_flight_ -= n * kDefaultTCPMSS; 100 clock_.AdvanceTime(one_ms_); 101 } 102 103 void LoseNPackets(int n) { 104 SendAlgorithmInterface::CongestionVector acked_packets; 105 SendAlgorithmInterface::CongestionVector lost_packets; 106 for (int i = 0; i < n; ++i) { 107 ++acked_sequence_number_; 108 lost_packets.push_back( 109 make_pair(acked_sequence_number_, standard_packet_)); 110 } 111 sender_->OnCongestionEvent( 112 false, bytes_in_flight_, acked_packets, lost_packets); 113 bytes_in_flight_ -= n * kDefaultTCPMSS; 114 } 115 116 // Does not increment acked_sequence_number_. 117 void LosePacket(QuicPacketSequenceNumber sequence_number) { 118 SendAlgorithmInterface::CongestionVector acked_packets; 119 SendAlgorithmInterface::CongestionVector lost_packets; 120 lost_packets.push_back( 121 make_pair(sequence_number, standard_packet_)); 122 sender_->OnCongestionEvent( 123 false, bytes_in_flight_, acked_packets, lost_packets); 124 bytes_in_flight_ -= kDefaultTCPMSS; 125 } 126 127 const QuicTime::Delta one_ms_; 128 MockClock clock_; 129 scoped_ptr<TcpCubicSenderPeer> sender_; 130 scoped_ptr<TcpReceiver> receiver_; 131 QuicPacketSequenceNumber sequence_number_; 132 QuicPacketSequenceNumber acked_sequence_number_; 133 QuicByteCount bytes_in_flight_; 134 TransmissionInfo standard_packet_; 135 }; 136 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(), 142 0, 143 HAS_RETRANSMITTABLE_DATA).IsZero()); 144 // Make sure we can send. 145 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 146 0, 147 HAS_RETRANSMITTABLE_DATA).IsZero()); 148 // And that window is un-affected. 149 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); 150 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()); 156 } 157 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(), 163 0, 164 HAS_RETRANSMITTABLE_DATA).IsZero()); 165 // Make sure we can send. 166 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 167 0, 168 HAS_RETRANSMITTABLE_DATA).IsZero()); 169 170 SendAvailableSendWindow(); 171 for (int i = 0; i < kNumberOfAcks; ++i) { 172 AckNPackets(2); 173 } 174 QuicByteCount bytes_to_send = sender_->SendWindow(); 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); 179 } 180 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(), 185 0, 186 HAS_RETRANSMITTABLE_DATA).IsZero()); 187 // Make sure we can send. 188 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 189 0, 190 HAS_RETRANSMITTABLE_DATA).IsZero()); 191 192 for (int i = 0; i < kNumberOfAcks; ++i) { 193 // Send our full send window. 194 SendAvailableSendWindow(); 195 AckNPackets(2); 196 } 197 QuicByteCount bytes_to_send = sender_->SendWindow(); 198 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, 199 bytes_to_send); 200 } 201 202 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { 203 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, 204 sender_->GetSlowStartThreshold()); 205 206 // Make sure that we fall out of slow start when we send ACK train longer 207 // than half the RTT, in this test case 30ms, which is more than 30 calls to 208 // Ack2Packets in one round. 209 // Since we start at 10 packet first round will be 5 second round 10 etc 210 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 211 const int kNumberOfAcks = 65; 212 for (int i = 0; i < kNumberOfAcks; ++i) { 213 // Send our full send window. 214 SendAvailableSendWindow(); 215 AckNPackets(2); 216 } 217 QuicByteCount expected_send_window = 218 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); 219 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 220 221 // We should now have fallen out of slow start. 222 // Testing Reno phase. 223 // We should need 140(65*2+10) ACK:ed packets before increasing window by 224 // one. 225 for (int i = 0; i < 69; ++i) { 226 SendAvailableSendWindow(); 227 AckNPackets(2); 228 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 229 } 230 SendAvailableSendWindow(); 231 AckNPackets(2); 232 QuicByteCount expected_ss_tresh = expected_send_window; 233 expected_send_window += kDefaultTCPMSS; 234 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 235 EXPECT_EQ(expected_ss_tresh, sender_->GetSlowStartThreshold()); 236 EXPECT_EQ(140u, sender_->slowstart_threshold()); 237 238 // Now RTO and ensure slow start gets reset. 239 EXPECT_TRUE(sender_->hybrid_slow_start().started()); 240 sender_->OnRetransmissionTimeout(true); 241 EXPECT_FALSE(sender_->hybrid_slow_start().started()); 242 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); 243 EXPECT_EQ(expected_send_window / 2 / kDefaultTCPMSS, 244 sender_->slowstart_threshold()); 245 246 // Now revert the RTO and ensure the CWND and slowstart threshold revert. 247 sender_->RevertRetransmissionTimeout(); 248 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 249 EXPECT_EQ(140u, sender_->slowstart_threshold()); 250 } 251 252 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { 253 const int kNumberOfAcks = 10; 254 for (int i = 0; i < kNumberOfAcks; ++i) { 255 // Send our full send window. 256 SendAvailableSendWindow(); 257 AckNPackets(2); 258 } 259 SendAvailableSendWindow(); 260 QuicByteCount expected_send_window = kDefaultWindowTCP + 261 (kDefaultTCPMSS * 2 * kNumberOfAcks); 262 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 263 264 // Lose a packet to exit slow start. 265 LoseNPackets(1); 266 267 // We should now have fallen out of slow start. 268 // We expect window to be cut in half by Reno. 269 expected_send_window /= 2; 270 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 271 272 // Testing Reno phase. 273 // We need to ack half of the pending packet before we can send again. 274 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; 275 AckNPackets(number_of_packets_in_window); 276 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 277 278 // We need to ack every packet in the window before we exit recovery. 279 for (size_t i = 0; i < number_of_packets_in_window; ++i) { 280 AckNPackets(1); 281 SendAvailableSendWindow(); 282 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 283 } 284 285 // We need to ack another window before we increase CWND by 1. 286 for (size_t i = 0; i < number_of_packets_in_window - 2; ++i) { 287 AckNPackets(1); 288 SendAvailableSendWindow(); 289 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 290 } 291 292 AckNPackets(1); 293 expected_send_window += kDefaultTCPMSS; 294 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 295 296 // Now RTO and ensure slow start gets reset. 297 EXPECT_TRUE(sender_->hybrid_slow_start().started()); 298 sender_->OnRetransmissionTimeout(true); 299 EXPECT_FALSE(sender_->hybrid_slow_start().started()); 300 } 301 302 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) { 303 // Test based on the first example in RFC6937. 304 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. 305 const int kNumberOfAcks = 5; 306 for (int i = 0; i < kNumberOfAcks; ++i) { 307 // Send our full send window. 308 SendAvailableSendWindow(); 309 AckNPackets(2); 310 } 311 SendAvailableSendWindow(); 312 QuicByteCount expected_send_window = kDefaultWindowTCP + 313 (kDefaultTCPMSS * 2 * kNumberOfAcks); 314 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 315 316 LoseNPackets(1); 317 318 // We should now have fallen out of slow start. 319 // We expect window to be cut in half by Reno. 320 expected_send_window /= 2; 321 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 322 323 // Testing TCP proportional rate reduction. 324 // We should send one packet for every two received acks over the remaining 325 // 18 outstanding packets. 326 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; 327 // The number of packets before we exit recovery is the original CWND minus 328 // the packet that has been lost and the one which triggered the loss. 329 size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1; 330 for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) { 331 AckNPackets(2); 332 EXPECT_TRUE(sender_->TimeUntilSend( 333 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); 334 EXPECT_EQ(1, SendAvailableSendWindow()); 335 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 336 } 337 338 // We need to ack another window before we increase CWND by 1. 339 for (size_t i = 0; i < number_of_packets_in_window; ++i) { 340 AckNPackets(1); 341 EXPECT_EQ(1, SendAvailableSendWindow()); 342 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 343 } 344 345 AckNPackets(1); 346 expected_send_window += kDefaultTCPMSS; 347 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 348 } 349 350 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { 351 // Test based on the second example in RFC6937, though we also implement 352 // forward acknowledgements, so the first two incoming acks will trigger 353 // PRR immediately. 354 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. 355 const int kNumberOfAcks = 5; 356 for (int i = 0; i < kNumberOfAcks; ++i) { 357 // Send our full send window. 358 SendAvailableSendWindow(); 359 AckNPackets(2); 360 } 361 SendAvailableSendWindow(); 362 QuicByteCount expected_send_window = kDefaultWindowTCP + 363 (kDefaultTCPMSS * 2 * kNumberOfAcks); 364 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 365 366 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK. 367 LoseNPackets(13); 368 // Immediately after the loss, ensure at least one packet can be sent. 369 // Losses without subsequent acks can occur with timer based loss detection. 370 EXPECT_TRUE(sender_->TimeUntilSend( 371 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); 372 AckNPackets(1); 373 374 // We should now have fallen out of slow start. 375 // We expect window to be cut in half by Reno. 376 expected_send_window /= 2; 377 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 378 379 // Only 2 packets should be allowed to be sent, per PRR-SSRB 380 EXPECT_EQ(2, SendAvailableSendWindow()); 381 382 // Ack the next packet, which triggers another loss. 383 LoseNPackets(1); 384 AckNPackets(1); 385 386 // Send 2 packets to simulate PRR-SSRB. 387 EXPECT_EQ(2, SendAvailableSendWindow()); 388 389 // Ack the next packet, which triggers another loss. 390 LoseNPackets(1); 391 AckNPackets(1); 392 393 // Send 2 packets to simulate PRR-SSRB. 394 EXPECT_EQ(2, SendAvailableSendWindow()); 395 396 AckNPackets(1); 397 EXPECT_EQ(2, SendAvailableSendWindow()); 398 399 AckNPackets(1); 400 EXPECT_EQ(2, SendAvailableSendWindow()); 401 402 // The window should not have changed. 403 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 404 405 // Exit recovery and return to sending at the new rate. 406 for (int i = 0; i < kNumberOfAcks; ++i) { 407 AckNPackets(1); 408 EXPECT_EQ(1, SendAvailableSendWindow()); 409 } 410 } 411 412 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { 413 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); 414 EXPECT_EQ(10000u, sender_->slowstart_threshold()); 415 416 // Expect the window to decrease to the minimum once the RTO fires 417 // and slow start threshold to be set to 1/2 of the CWND. 418 sender_->OnRetransmissionTimeout(true); 419 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->SendWindow()); 420 EXPECT_EQ(5u, sender_->slowstart_threshold()); 421 422 // Now repair the RTO and ensure the slowstart threshold reverts. 423 sender_->RevertRetransmissionTimeout(); 424 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); 425 EXPECT_EQ(10000u, sender_->slowstart_threshold()); 426 } 427 428 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) { 429 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); 430 431 // Expect the window to remain unchanged if the RTO fires but no 432 // packets are retransmitted. 433 sender_->OnRetransmissionTimeout(false); 434 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); 435 } 436 437 TEST_F(TcpCubicSenderTest, RetransmissionDelay) { 438 const int64 kRttMs = 10; 439 const int64 kDeviationMs = 3; 440 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); 441 442 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs), 443 QuicTime::Delta::Zero(), clock_.Now()); 444 445 // Initial value is to set the median deviation to half of the initial 446 // rtt, the median in then multiplied by a factor of 4 and finally the 447 // smoothed rtt is added which is the initial rtt. 448 QuicTime::Delta expected_delay = 449 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); 450 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); 451 452 for (int i = 0; i < 100; ++i) { 453 // Run to make sure that we converge. 454 sender_->rtt_stats_.UpdateRtt( 455 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), 456 QuicTime::Delta::Zero(), clock_.Now()); 457 sender_->rtt_stats_.UpdateRtt( 458 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), 459 QuicTime::Delta::Zero(), clock_.Now()); 460 } 461 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); 462 463 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1); 464 EXPECT_NEAR(expected_delay.ToMilliseconds(), 465 sender_->RetransmissionDelay().ToMilliseconds(), 466 1); 467 EXPECT_EQ(static_cast<int64>( 468 sender_->GetCongestionWindow() * kNumMicrosPerSecond / 469 sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()), 470 sender_->BandwidthEstimate().ToBytesPerSecond()); 471 } 472 473 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { 474 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; 475 const int kNumberOfAcks = 100; 476 sender_.reset( 477 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); 478 479 for (int i = 0; i < kNumberOfAcks; ++i) { 480 // Send our full send window. 481 SendAvailableSendWindow(); 482 AckNPackets(2); 483 } 484 QuicByteCount expected_send_window = 485 kMaxCongestionWindowTCP * kDefaultTCPMSS; 486 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 487 } 488 489 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { 490 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; 491 const int kNumberOfAcks = 1000; 492 sender_.reset( 493 new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP)); 494 495 SendAvailableSendWindow(); 496 AckNPackets(2); 497 // Make sure we fall out of slow start. 498 LoseNPackets(1); 499 500 for (int i = 0; i < kNumberOfAcks; ++i) { 501 // Send our full send window. 502 SendAvailableSendWindow(); 503 AckNPackets(2); 504 } 505 506 QuicByteCount expected_send_window = 507 kMaxCongestionWindowTCP * kDefaultTCPMSS; 508 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 509 } 510 511 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { 512 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; 513 // Set to 10000 to compensate for small cubic alpha. 514 const int kNumberOfAcks = 10000; 515 516 sender_.reset( 517 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); 518 519 SendAvailableSendWindow(); 520 AckNPackets(2); 521 // Make sure we fall out of slow start. 522 LoseNPackets(1); 523 524 for (int i = 0; i < kNumberOfAcks; ++i) { 525 // Send our full send window. 526 SendAvailableSendWindow(); 527 AckNPackets(2); 528 } 529 530 QuicByteCount expected_send_window = 531 kMaxCongestionWindowTCP * kDefaultTCPMSS; 532 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 533 } 534 535 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { 536 SendAvailableSendWindow(); 537 const QuicByteCount initial_window = sender_->GetCongestionWindow(); 538 LosePacket(acked_sequence_number_ + 1); 539 const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); 540 EXPECT_GT(initial_window, post_loss_window); 541 LosePacket(acked_sequence_number_ + 3); 542 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); 543 LosePacket(sequence_number_ - 1); 544 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); 545 546 // Lose a later packet and ensure the window decreases. 547 LosePacket(sequence_number_); 548 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow()); 549 } 550 551 TEST_F(TcpCubicSenderTest, DontTrackAckPackets) { 552 // Send a packet with no retransmittable data, and ensure it's not tracked. 553 EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, 554 sequence_number_++, kDefaultTCPMSS, 555 NO_RETRANSMITTABLE_DATA)); 556 557 // Send a data packet with retransmittable data, and ensure it is tracked. 558 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, 559 sequence_number_++, kDefaultTCPMSS, 560 HAS_RETRANSMITTABLE_DATA)); 561 } 562 563 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { 564 QuicTcpCongestionWindow congestion_window = sender_->congestion_window(); 565 QuicConfig config; 566 QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window); 567 568 sender_->SetFromConfig(config, true); 569 EXPECT_EQ(2 * congestion_window, sender_->congestion_window()); 570 571 // Verify that kCOPT: kIW10 forces the congestion window to the 572 // default of 10 regardless of ReceivedInitialWindow. 573 QuicTagVector options; 574 options.push_back(kIW10); 575 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); 576 sender_->SetFromConfig(config, true); 577 EXPECT_EQ(congestion_window, sender_->congestion_window()); 578 } 579 580 TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) { 581 // Ack 10 packets in 5 acks to raise the CWND to 20. 582 const int kNumberOfAcks = 5; 583 for (int i = 0; i < kNumberOfAcks; ++i) { 584 // Send our full send window. 585 SendAvailableSendWindow(); 586 AckNPackets(2); 587 } 588 SendAvailableSendWindow(); 589 QuicByteCount expected_send_window = kDefaultWindowTCP + 590 (kDefaultTCPMSS * 2 * kNumberOfAcks); 591 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 592 593 LoseNPackets(1); 594 595 // We should now have fallen out of slow start, and window should be cut in 596 // half by Reno. New cwnd should be 10. 597 expected_send_window /= 2; 598 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 599 600 // No congestion window growth should occur in recovery phase, i.e., 601 // until the currently outstanding 20 packets are acked. 602 for (int i = 0; i < 10; ++i) { 603 // Send our full send window. 604 SendAvailableSendWindow(); 605 AckNPackets(2); 606 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 607 } 608 609 // Out of recovery now. Congestion window should not grow during RTT. 610 for (int i = 0; i < 4; ++i) { 611 // Send our full send window. 612 SendAvailableSendWindow(); 613 AckNPackets(2); 614 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 615 } 616 617 // Next ack should cause congestion window to grow by 1MSS. 618 AckNPackets(2); 619 expected_send_window += kDefaultTCPMSS; 620 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); 621 } 622 623 } // namespace test 624 } // namespace net 625