| 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 uint32 kDefaultWindowTCP = kDefaultInitialWindow * kDefaultTCPMSS; |
| 25 const uint32 kDefaultWindowTCP = kInitialCongestionWindow * kDefaultTCPMSS; | |
| 26 const float kRenoBeta = 0.7f; // Reno backoff factor. | 25 const float kRenoBeta = 0.7f; // Reno backoff factor. |
| 27 | 26 |
| 28 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 27 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
| 29 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; | 28 const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000; |
| 30 | 29 |
| 31 class TcpCubicSenderPeer : public TcpCubicSender { | 30 class TcpCubicSenderPeer : public TcpCubicSender { |
| 32 public: | 31 public: |
| 33 TcpCubicSenderPeer(const QuicClock* clock, | 32 TcpCubicSenderPeer(const QuicClock* clock, |
| 34 bool reno, | 33 bool reno, |
| 35 QuicPacketCount max_tcp_congestion_window) | 34 QuicPacketCount max_tcp_congestion_window) |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, | 180 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, |
| 182 bytes_to_send); | 181 bytes_to_send); |
| 183 } | 182 } |
| 184 | 183 |
| 185 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { | 184 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { |
| 186 const int kNumberOfAcks = 20; | 185 const int kNumberOfAcks = 20; |
| 187 // At startup make sure we can send. | 186 // At startup make sure we can send. |
| 188 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 187 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), |
| 189 0, | 188 0, |
| 190 HAS_RETRANSMITTABLE_DATA).IsZero()); | 189 HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 190 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); |
| 191 EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate()); |
| 191 // Make sure we can send. | 192 // Make sure we can send. |
| 192 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 193 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), |
| 193 0, | 194 0, |
| 194 HAS_RETRANSMITTABLE_DATA).IsZero()); | 195 HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 195 | 196 |
| 196 for (int i = 0; i < kNumberOfAcks; ++i) { | 197 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 197 // Send our full send window. | 198 // Send our full send window. |
| 198 SendAvailableSendWindow(); | 199 SendAvailableSendWindow(); |
| 199 AckNPackets(2); | 200 AckNPackets(2); |
| 200 } | 201 } |
| 201 QuicByteCount bytes_to_send = sender_->GetCongestionWindow(); | 202 const QuicByteCount cwnd = sender_->GetCongestionWindow(); |
| 202 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, | 203 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd); |
| 203 bytes_to_send); | 204 EXPECT_FALSE(sender_->HasReliableBandwidthEstimate()); |
| 205 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta( |
| 206 cwnd, sender_->rtt_stats_.smoothed_rtt()), |
| 207 sender_->BandwidthEstimate()); |
| 204 } | 208 } |
| 205 | 209 |
| 206 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 210 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
| 207 sender_->SetNumEmulatedConnections(1); | 211 sender_->SetNumEmulatedConnections(1); |
| 208 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, | 212 EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS, |
| 209 sender_->GetSlowStartThreshold()); | 213 sender_->GetSlowStartThreshold()); |
| 210 | 214 |
| 211 // Make sure that we fall out of slow start when we send ACK train longer | 215 // Make sure that we fall out of slow start when we send ACK train longer |
| 212 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 216 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
| 213 // Ack2Packets in one round. | 217 // Ack2Packets in one round. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 298 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 295 | 299 |
| 296 // Now RTO and ensure slow start gets reset. | 300 // Now RTO and ensure slow start gets reset. |
| 297 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 301 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
| 298 sender_->OnRetransmissionTimeout(true); | 302 sender_->OnRetransmissionTimeout(true); |
| 299 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 303 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
| 300 } | 304 } |
| 301 | 305 |
| 302 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) { | 306 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) { |
| 303 SendAvailableSendWindow(); | 307 SendAvailableSendWindow(); |
| 304 LoseNPackets(kInitialCongestionWindow - 1); | 308 LoseNPackets(kDefaultInitialWindow - 1); |
| 305 AckNPackets(1); | 309 AckNPackets(1); |
| 306 // PRR will allow 2 packets for every ack during recovery. | 310 // PRR will allow 2 packets for every ack during recovery. |
| 307 EXPECT_EQ(2, SendAvailableSendWindow()); | 311 EXPECT_EQ(2, SendAvailableSendWindow()); |
| 308 // Simulate abandoning all packets by supplying a bytes_in_flight of 0. | 312 // Simulate abandoning all packets by supplying a bytes_in_flight of 0. |
| 309 // PRR should now allow a packet to be sent, even though prr's state | 313 // PRR should now allow a packet to be sent, even though prr's state |
| 310 // variables believe it has sent enough packets. | 314 // variables believe it has sent enough packets. |
| 311 EXPECT_EQ(QuicTime::Delta::Zero(), | 315 EXPECT_EQ(QuicTime::Delta::Zero(), |
| 312 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); | 316 sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); |
| 313 } | 317 } |
| 314 | 318 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 // Run to make sure that we converge. | 466 // Run to make sure that we converge. |
| 463 sender_->rtt_stats_.UpdateRtt( | 467 sender_->rtt_stats_.UpdateRtt( |
| 464 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), | 468 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), |
| 465 QuicTime::Delta::Zero(), clock_.Now()); | 469 QuicTime::Delta::Zero(), clock_.Now()); |
| 466 sender_->rtt_stats_.UpdateRtt( | 470 sender_->rtt_stats_.UpdateRtt( |
| 467 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), | 471 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), |
| 468 QuicTime::Delta::Zero(), clock_.Now()); | 472 QuicTime::Delta::Zero(), clock_.Now()); |
| 469 } | 473 } |
| 470 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); | 474 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); |
| 471 | 475 |
| 472 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1); | 476 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); |
| 473 EXPECT_NEAR(expected_delay.ToMilliseconds(), | 477 EXPECT_NEAR(expected_delay.ToMilliseconds(), |
| 474 sender_->RetransmissionDelay().ToMilliseconds(), | 478 sender_->RetransmissionDelay().ToMilliseconds(), |
| 475 1); | 479 1); |
| 476 EXPECT_EQ(static_cast<int64>( | 480 EXPECT_EQ(static_cast<int64>( |
| 477 sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 481 sender_->GetCongestionWindow() * kNumMicrosPerSecond / |
| 478 sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()), | 482 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), |
| 479 sender_->BandwidthEstimate().ToBytesPerSecond()); | 483 sender_->BandwidthEstimate().ToBytesPerSecond()); |
| 480 } | 484 } |
| 481 | 485 |
| 482 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { | 486 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { |
| 483 const QuicPacketCount kMaxCongestionWindowTCP = 50; | 487 const QuicPacketCount kMaxCongestionWindowTCP = 50; |
| 484 const int kNumberOfAcks = 100; | 488 const int kNumberOfAcks = 100; |
| 485 sender_.reset( | 489 sender_.reset( |
| 486 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | 490 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); |
| 487 | 491 |
| 488 for (int i = 0; i < kNumberOfAcks; ++i) { | 492 for (int i = 0; i < kNumberOfAcks; ++i) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 687 |
| 684 // Next ack should cause congestion window to grow by 1MSS. | 688 // Next ack should cause congestion window to grow by 1MSS. |
| 685 SendAvailableSendWindow(); | 689 SendAvailableSendWindow(); |
| 686 AckNPackets(2); | 690 AckNPackets(2); |
| 687 expected_send_window += kDefaultTCPMSS; | 691 expected_send_window += kDefaultTCPMSS; |
| 688 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 692 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 689 } | 693 } |
| 690 | 694 |
| 691 } // namespace test | 695 } // namespace test |
| 692 } // namespace net | 696 } // namespace net |
| OLD | NEW |