| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "net/quic/congestion_control/rtt_stats.h" | 9 #include "net/quic/congestion_control/rtt_stats.h" |
| 10 #include "net/quic/congestion_control/tcp_cubic_sender.h" | 10 #include "net/quic/congestion_control/tcp_cubic_sender.h" |
| 11 #include "net/quic/congestion_control/tcp_receiver.h" | 11 #include "net/quic/congestion_control/tcp_receiver.h" |
| 12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
| 13 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
| 14 #include "net/quic/test_tools/mock_clock.h" | 14 #include "net/quic/test_tools/mock_clock.h" |
| 15 #include "net/quic/test_tools/quic_config_peer.h" | 15 #include "net/quic/test_tools/quic_config_peer.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using std::make_pair; | 18 using std::make_pair; |
| 19 using std::min; | 19 using std::min; |
| 20 | 20 |
| 21 namespace net { | 21 namespace net { |
| 22 namespace test { | 22 namespace test { |
| 23 | 23 |
| 24 const int64 kInitialCongestionWindow = 10; | 24 const int64 kInitialCongestionWindow = 10; |
| 25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; | 25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; |
| 26 const float kRenoBeta = 0.7f; // Reno backoff factor. |
| 26 | 27 |
| 27 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 28 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
| 28 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; | 29 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; |
| 29 | 30 |
| 30 class TcpCubicSenderPeer : public TcpCubicSender { | 31 class TcpCubicSenderPeer : public TcpCubicSender { |
| 31 public: | 32 public: |
| 32 TcpCubicSenderPeer(const QuicClock* clock, | 33 TcpCubicSenderPeer(const QuicClock* clock, |
| 33 bool reno, | 34 bool reno, |
| 34 QuicPacketCount max_tcp_congestion_window) | 35 QuicPacketCount max_tcp_congestion_window) |
| 35 : TcpCubicSender( | 36 : TcpCubicSender( |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 SendAvailableSendWindow(); | 258 SendAvailableSendWindow(); |
| 258 AckNPackets(2); | 259 AckNPackets(2); |
| 259 } | 260 } |
| 260 SendAvailableSendWindow(); | 261 SendAvailableSendWindow(); |
| 261 QuicByteCount expected_send_window = kDefaultWindowTCP + | 262 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 262 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 263 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 263 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 264 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 264 | 265 |
| 265 // Lose a packet to exit slow start. | 266 // Lose a packet to exit slow start. |
| 266 LoseNPackets(1); | 267 LoseNPackets(1); |
| 268 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS; |
| 267 | 269 |
| 268 // We should now have fallen out of slow start. | 270 // We should now have fallen out of slow start with a reduced window. |
| 269 // We expect window to be cut in half by Reno. | 271 expected_send_window *= kRenoBeta; |
| 270 expected_send_window /= 2; | |
| 271 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 272 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 272 | 273 |
| 273 // Testing Reno phase. | 274 // Recovery phase. We need to ack every packet in the recovery window before |
| 274 // We need to ack half of the pending packet before we can send again. | 275 // we exit recovery. |
| 275 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 276 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
| 276 AckNPackets(number_of_packets_in_window); | 277 DVLOG(1) << "number_packets: " << number_of_packets_in_window; |
| 278 AckNPackets(packets_in_recovery_window); |
| 279 SendAvailableSendWindow(); |
| 277 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 280 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 278 | 281 |
| 279 // We need to ack every packet in the window before we exit recovery. | 282 // We need to ack an entire window before we increase CWND by 1. |
| 280 for (size_t i = 0; i < number_of_packets_in_window; ++i) { | 283 AckNPackets(number_of_packets_in_window - 2); |
| 281 AckNPackets(1); | 284 SendAvailableSendWindow(); |
| 282 SendAvailableSendWindow(); | 285 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 283 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
| 284 } | |
| 285 | 286 |
| 286 // We need to ack another window before we increase CWND by 1. | 287 // Next ack should increase cwnd by 1. |
| 287 for (size_t i = 0; i < number_of_packets_in_window - 2; ++i) { | |
| 288 AckNPackets(1); | |
| 289 SendAvailableSendWindow(); | |
| 290 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
| 291 } | |
| 292 | |
| 293 AckNPackets(1); | 288 AckNPackets(1); |
| 294 expected_send_window += kDefaultTCPMSS; | 289 expected_send_window += kDefaultTCPMSS; |
| 295 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 290 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 296 | 291 |
| 297 // Now RTO and ensure slow start gets reset. | 292 // Now RTO and ensure slow start gets reset. |
| 298 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 293 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
| 299 sender_->OnRetransmissionTimeout(true); | 294 sender_->OnRetransmissionTimeout(true); |
| 300 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 295 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
| 301 } | 296 } |
| 302 | 297 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 323 SendAvailableSendWindow(); | 318 SendAvailableSendWindow(); |
| 324 AckNPackets(2); | 319 AckNPackets(2); |
| 325 } | 320 } |
| 326 SendAvailableSendWindow(); | 321 SendAvailableSendWindow(); |
| 327 QuicByteCount expected_send_window = kDefaultWindowTCP + | 322 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 328 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 323 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 329 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 324 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 330 | 325 |
| 331 LoseNPackets(1); | 326 LoseNPackets(1); |
| 332 | 327 |
| 333 // We should now have fallen out of slow start. | 328 // We should now have fallen out of slow start with a reduced window. |
| 334 // We expect window to be cut in half by Reno. | 329 size_t send_window_before_loss = expected_send_window; |
| 335 expected_send_window /= 2; | 330 expected_send_window *= kRenoBeta; |
| 336 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 331 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 337 | 332 |
| 338 // Testing TCP proportional rate reduction. | 333 // Testing TCP proportional rate reduction. |
| 339 // We should send one packet for every two received acks over the remaining | 334 // We should send packets paced over the received acks for the remaining |
| 340 // 18 outstanding packets. | 335 // outstanding packets. The number of packets before we exit recovery is the |
| 341 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 336 // original CWND minus the packet that has been lost and the one which |
| 342 // The number of packets before we exit recovery is the original CWND minus | 337 // triggered the loss. |
| 343 // the packet that has been lost and the one which triggered the loss. | 338 size_t remaining_packets_in_recovery = |
| 344 size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1; | 339 send_window_before_loss / kDefaultTCPMSS - 2; |
| 345 for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) { | 340 |
| 346 AckNPackets(2); | 341 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) { |
| 347 EXPECT_TRUE(sender_->TimeUntilSend( | 342 AckNPackets(1); |
| 348 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); | 343 SendAvailableSendWindow(); |
| 349 EXPECT_EQ(1, SendAvailableSendWindow()); | |
| 350 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 344 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 351 } | 345 } |
| 352 | 346 |
| 353 // We need to ack another window before we increase CWND by 1. | 347 // We need to ack another window before we increase CWND by 1. |
| 348 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
| 354 for (size_t i = 0; i < number_of_packets_in_window; ++i) { | 349 for (size_t i = 0; i < number_of_packets_in_window; ++i) { |
| 355 AckNPackets(1); | 350 AckNPackets(1); |
| 356 EXPECT_EQ(1, SendAvailableSendWindow()); | 351 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 357 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 352 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 358 } | 353 } |
| 359 | 354 |
| 360 AckNPackets(1); | 355 AckNPackets(1); |
| 361 expected_send_window += kDefaultTCPMSS; | 356 expected_send_window += kDefaultTCPMSS; |
| 362 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 357 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 363 } | 358 } |
| 364 | 359 |
| 365 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { | 360 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { |
| 366 sender_->SetNumEmulatedConnections(1); | 361 sender_->SetNumEmulatedConnections(1); |
| 367 // Test based on the second example in RFC6937, though we also implement | 362 // Test based on the second example in RFC6937, though we also implement |
| 368 // forward acknowledgements, so the first two incoming acks will trigger | 363 // forward acknowledgements, so the first two incoming acks will trigger |
| 369 // PRR immediately. | 364 // PRR immediately. |
| 370 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 365 // Ack 20 packets in 10 acks to raise the CWND to 30. |
| 371 const int kNumberOfAcks = 5; | 366 const int kNumberOfAcks = 10; |
| 372 for (int i = 0; i < kNumberOfAcks; ++i) { | 367 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 373 // Send our full send window. | 368 // Send our full send window. |
| 374 SendAvailableSendWindow(); | 369 SendAvailableSendWindow(); |
| 375 AckNPackets(2); | 370 AckNPackets(2); |
| 376 } | 371 } |
| 377 SendAvailableSendWindow(); | 372 SendAvailableSendWindow(); |
| 378 QuicByteCount expected_send_window = kDefaultWindowTCP + | 373 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 379 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 374 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 380 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 375 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 381 | 376 |
| 382 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK. | 377 // Lose one more than the congestion window reduction, so that after loss, |
| 383 LoseNPackets(13); | 378 // bytes_in_flight is lesser than the congestion window. |
| 379 size_t send_window_after_loss = kRenoBeta * expected_send_window; |
| 380 size_t num_packets_to_lose = |
| 381 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1; |
| 382 LoseNPackets(num_packets_to_lose); |
| 384 // Immediately after the loss, ensure at least one packet can be sent. | 383 // Immediately after the loss, ensure at least one packet can be sent. |
| 385 // Losses without subsequent acks can occur with timer based loss detection. | 384 // Losses without subsequent acks can occur with timer based loss detection. |
| 386 EXPECT_TRUE(sender_->TimeUntilSend( | 385 EXPECT_TRUE(sender_->TimeUntilSend( |
| 387 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); | 386 clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 388 AckNPackets(1); | 387 AckNPackets(1); |
| 389 | 388 |
| 390 // We should now have fallen out of slow start. | 389 // We should now have fallen out of slow start with a reduced window. |
| 391 // We expect window to be cut in half by Reno. | 390 expected_send_window *= kRenoBeta; |
| 392 expected_send_window /= 2; | |
| 393 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 391 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 394 | 392 |
| 395 // Only 2 packets should be allowed to be sent, per PRR-SSRB | 393 // Only 2 packets should be allowed to be sent, per PRR-SSRB |
| 396 EXPECT_EQ(2, SendAvailableSendWindow()); | 394 EXPECT_EQ(2, SendAvailableSendWindow()); |
| 397 | 395 |
| 398 // Ack the next packet, which triggers another loss. | 396 // Ack the next packet, which triggers another loss. |
| 399 LoseNPackets(1); | 397 LoseNPackets(1); |
| 400 AckNPackets(1); | 398 AckNPackets(1); |
| 401 | 399 |
| 402 // Send 2 packets to simulate PRR-SSRB. | 400 // Send 2 packets to simulate PRR-SSRB. |
| 403 EXPECT_EQ(2, SendAvailableSendWindow()); | 401 EXPECT_EQ(2, SendAvailableSendWindow()); |
| 404 | 402 |
| 405 // Ack the next packet, which triggers another loss. | 403 // Ack the next packet, which triggers another loss. |
| 406 LoseNPackets(1); | 404 LoseNPackets(1); |
| 407 AckNPackets(1); | 405 AckNPackets(1); |
| 408 | 406 |
| 409 // Send 2 packets to simulate PRR-SSRB. | 407 // Send 2 packets to simulate PRR-SSRB. |
| 410 EXPECT_EQ(2, SendAvailableSendWindow()); | 408 EXPECT_EQ(2, SendAvailableSendWindow()); |
| 411 | 409 |
| 412 AckNPackets(1); | |
| 413 EXPECT_EQ(2, SendAvailableSendWindow()); | |
| 414 | |
| 415 AckNPackets(1); | |
| 416 EXPECT_EQ(2, SendAvailableSendWindow()); | |
| 417 | |
| 418 // The window should not have changed. | |
| 419 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
| 420 | |
| 421 // Exit recovery and return to sending at the new rate. | 410 // Exit recovery and return to sending at the new rate. |
| 422 for (int i = 0; i < kNumberOfAcks; ++i) { | 411 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 423 AckNPackets(1); | 412 AckNPackets(1); |
| 424 EXPECT_EQ(1, SendAvailableSendWindow()); | 413 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 425 } | 414 } |
| 426 } | 415 } |
| 427 | 416 |
| 428 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { | 417 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) { |
| 429 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 418 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 430 EXPECT_EQ(10000u, sender_->slowstart_threshold()); | 419 EXPECT_EQ(10000u, sender_->slowstart_threshold()); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 SendAvailableSendWindow(); | 591 SendAvailableSendWindow(); |
| 603 AckNPackets(2); | 592 AckNPackets(2); |
| 604 } | 593 } |
| 605 SendAvailableSendWindow(); | 594 SendAvailableSendWindow(); |
| 606 QuicByteCount expected_send_window = kDefaultWindowTCP + | 595 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 607 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 596 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 608 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 597 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 609 | 598 |
| 610 LoseNPackets(1); | 599 LoseNPackets(1); |
| 611 | 600 |
| 612 // We should now have fallen out of slow start, and window should be cut in | 601 // We should now have fallen out of slow start with a reduced window. |
| 613 // half by Reno. New cwnd should be 10. | 602 expected_send_window *= kRenoBeta; |
| 614 expected_send_window /= 2; | |
| 615 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 603 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 616 | 604 |
| 617 // No congestion window growth should occur in recovery phase, i.e., until the | 605 // No congestion window growth should occur in recovery phase, i.e., until the |
| 618 // currently outstanding 20 packets are acked. | 606 // currently outstanding 20 packets are acked. |
| 619 for (int i = 0; i < 10; ++i) { | 607 for (int i = 0; i < 10; ++i) { |
| 620 // Send our full send window. | 608 // Send our full send window. |
| 621 SendAvailableSendWindow(); | 609 SendAvailableSendWindow(); |
| 622 EXPECT_TRUE(sender_->InRecovery()); | 610 EXPECT_TRUE(sender_->InRecovery()); |
| 623 AckNPackets(2); | 611 AckNPackets(2); |
| 624 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 612 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 625 } | 613 } |
| 626 EXPECT_FALSE(sender_->InRecovery()); | 614 EXPECT_FALSE(sender_->InRecovery()); |
| 627 | 615 |
| 628 // Out of recovery now. Congestion window should not grow for half an RTT. | 616 // Out of recovery now. Congestion window should not grow for half an RTT. |
| 617 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS; |
| 618 SendAvailableSendWindow(); |
| 619 AckNPackets(packets_in_send_window / 2 - 2); |
| 620 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 621 |
| 622 // Next ack should increase congestion window by 1MSS. |
| 629 SendAvailableSendWindow(); | 623 SendAvailableSendWindow(); |
| 630 AckNPackets(2); | 624 AckNPackets(2); |
| 625 expected_send_window += kDefaultTCPMSS; |
| 626 packets_in_send_window += 1; |
| 631 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 627 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 632 | 628 |
| 633 // Next ack will be the 5th and should increase congestion window by 1MSS. | 629 // Congestion window should remain steady again for half an RTT. |
| 630 SendAvailableSendWindow(); |
| 631 AckNPackets(packets_in_send_window / 2 - 1); |
| 632 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 633 |
| 634 // Next ack should cause congestion window to grow by 1MSS. |
| 635 SendAvailableSendWindow(); |
| 634 AckNPackets(2); | 636 AckNPackets(2); |
| 635 expected_send_window += kDefaultTCPMSS; | 637 expected_send_window += kDefaultTCPMSS; |
| 636 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 638 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 637 | |
| 638 for (int i = 0; i < 2; ++i) { | |
| 639 SendAvailableSendWindow(); | |
| 640 AckNPackets(2); | |
| 641 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
| 642 } | |
| 643 | |
| 644 // Next ack should cause congestion window to grow by 1MSS. | |
| 645 AckNPackets(2); | |
| 646 expected_send_window += kDefaultTCPMSS; | |
| 647 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | |
| 648 } | 639 } |
| 649 | 640 |
| 650 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { | 641 TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { |
| 651 sender_->SetNumEmulatedConnections(1); | 642 sender_->SetNumEmulatedConnections(1); |
| 652 // Ack 10 packets in 5 acks to raise the CWND to 20. | 643 // Ack 10 packets in 5 acks to raise the CWND to 20. |
| 653 const int kNumberOfAcks = 5; | 644 const int kNumberOfAcks = 5; |
| 654 for (int i = 0; i < kNumberOfAcks; ++i) { | 645 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 655 // Send our full send window. | 646 // Send our full send window. |
| 656 SendAvailableSendWindow(); | 647 SendAvailableSendWindow(); |
| 657 AckNPackets(2); | 648 AckNPackets(2); |
| 658 } | 649 } |
| 659 SendAvailableSendWindow(); | 650 SendAvailableSendWindow(); |
| 660 QuicByteCount expected_send_window = kDefaultWindowTCP + | 651 QuicByteCount expected_send_window = kDefaultWindowTCP + |
| 661 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 652 (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 662 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 653 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 663 | 654 |
| 664 LoseNPackets(1); | 655 LoseNPackets(1); |
| 665 | 656 |
| 666 // We should now have fallen out of slow start, and window should be cut in | 657 // We should now have fallen out of slow start with a reduced window. |
| 667 // half by Reno. New cwnd should be 10. | 658 expected_send_window *= kRenoBeta; |
| 668 expected_send_window /= 2; | |
| 669 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 659 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 670 | 660 |
| 671 // No congestion window growth should occur in recovery phase, i.e., until the | 661 // No congestion window growth should occur in recovery phase, i.e., until the |
| 672 // currently outstanding 20 packets are acked. | 662 // currently outstanding 20 packets are acked. |
| 673 for (int i = 0; i < 10; ++i) { | 663 for (int i = 0; i < 10; ++i) { |
| 674 // Send our full send window. | 664 // Send our full send window. |
| 675 SendAvailableSendWindow(); | 665 SendAvailableSendWindow(); |
| 676 EXPECT_TRUE(sender_->InRecovery()); | 666 EXPECT_TRUE(sender_->InRecovery()); |
| 677 AckNPackets(2); | 667 AckNPackets(2); |
| 678 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 668 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 679 } | 669 } |
| 680 EXPECT_FALSE(sender_->InRecovery()); | 670 EXPECT_FALSE(sender_->InRecovery()); |
| 681 | 671 |
| 682 // Out of recovery now. Congestion window should not grow during RTT. | 672 // Out of recovery now. Congestion window should not grow during RTT. |
| 683 for (int i = 0; i < 4; ++i) { | 673 for (uint64 i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) { |
| 684 // Send our full send window. | 674 // Send our full send window. |
| 685 SendAvailableSendWindow(); | 675 SendAvailableSendWindow(); |
| 686 AckNPackets(2); | 676 AckNPackets(2); |
| 687 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 677 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 688 } | 678 } |
| 689 | 679 |
| 690 // Next ack should cause congestion window to grow by 1MSS. | 680 // Next ack should cause congestion window to grow by 1MSS. |
| 681 SendAvailableSendWindow(); |
| 691 AckNPackets(2); | 682 AckNPackets(2); |
| 692 expected_send_window += kDefaultTCPMSS; | 683 expected_send_window += kDefaultTCPMSS; |
| 693 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 684 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 694 } | 685 } |
| 695 | 686 |
| 696 } // namespace test | 687 } // namespace test |
| 697 } // namespace net | 688 } // namespace net |
| OLD | NEW |