| OLD | NEW | 
|    1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |    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 |    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 "net/quic/congestion_control/tcp_cubic_bytes_sender.h" |    5 #include "net/quic/congestion_control/tcp_cubic_bytes_sender.h" | 
|    6  |    6  | 
|    7 #include <algorithm> |    7 #include <algorithm> | 
|    8  |    8  | 
|    9 #include "base/logging.h" |    9 #include "base/logging.h" | 
|   10 #include "base/memory/scoped_ptr.h" |   10 #include "base/memory/scoped_ptr.h" | 
|   11 #include "net/quic/congestion_control/rtt_stats.h" |   11 #include "net/quic/congestion_control/rtt_stats.h" | 
|   12 #include "net/quic/crypto/crypto_protocol.h" |   12 #include "net/quic/crypto/crypto_protocol.h" | 
|   13 #include "net/quic/proto/cached_network_parameters.pb.h" |   13 #include "net/quic/proto/cached_network_parameters.pb.h" | 
|   14 #include "net/quic/quic_flags.h" |   14 #include "net/quic/quic_flags.h" | 
|   15 #include "net/quic/quic_protocol.h" |   15 #include "net/quic/quic_protocol.h" | 
|   16 #include "net/quic/quic_utils.h" |   16 #include "net/quic/quic_utils.h" | 
|   17 #include "net/quic/test_tools/mock_clock.h" |   17 #include "net/quic/test_tools/mock_clock.h" | 
|   18 #include "net/quic/test_tools/quic_config_peer.h" |   18 #include "net/quic/test_tools/quic_config_peer.h" | 
|   19 #include "net/quic/test_tools/quic_test_utils.h" |   19 #include "net/quic/test_tools/quic_test_utils.h" | 
|   20 #include "testing/gtest/include/gtest/gtest.h" |   20 #include "testing/gtest/include/gtest/gtest.h" | 
|   21  |   21  | 
|   22 namespace net { |   22 namespace net { | 
|   23 namespace test { |   23 namespace test { | 
|   24  |   24  | 
|   25 // TODO(ianswett): A number of theses tests were written with the assumption of |   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 |   26 // an initial CWND of 10. They have carefully calculated values which should be | 
|   27 // updated to be based on kInitialCongestionWindowInsecure. |   27 // updated to be based on kInitialCongestionWindowInsecure. | 
|   28 const uint32 kInitialCongestionWindowPackets = 10; |   28 const uint32_t kInitialCongestionWindowPackets = 10; | 
|   29 const uint32 kDefaultWindowTCP = |   29 const uint32_t kDefaultWindowTCP = | 
|   30     kInitialCongestionWindowPackets * kDefaultTCPMSS; |   30     kInitialCongestionWindowPackets * kDefaultTCPMSS; | 
|   31 const float kRenoBeta = 0.7f;  // Reno backoff factor. |   31 const float kRenoBeta = 0.7f;  // Reno backoff factor. | 
|   32  |   32  | 
|   33 class TcpCubicBytesSenderPeer : public TcpCubicBytesSender { |   33 class TcpCubicBytesSenderPeer : public TcpCubicBytesSender { | 
|   34  public: |   34  public: | 
|   35   TcpCubicBytesSenderPeer(const QuicClock* clock, bool reno) |   35   TcpCubicBytesSenderPeer(const QuicClock* clock, bool reno) | 
|   36       : TcpCubicBytesSender(clock, |   36       : TcpCubicBytesSender(clock, | 
|   37                             &rtt_stats_, |   37                             &rtt_stats_, | 
|   38                             reno, |   38                             reno, | 
|   39                             kInitialCongestionWindowPackets, |   39                             kInitialCongestionWindowPackets, | 
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  364 TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindowNoRetransmission) { |  364 TEST_F(TcpCubicBytesSenderTest, RTOCongestionWindowNoRetransmission) { | 
|  365   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |  365   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 
|  366  |  366  | 
|  367   // Expect the window to remain unchanged if the RTO fires but no packets are |  367   // Expect the window to remain unchanged if the RTO fires but no packets are | 
|  368   // retransmitted. |  368   // retransmitted. | 
|  369   sender_->OnRetransmissionTimeout(false); |  369   sender_->OnRetransmissionTimeout(false); | 
|  370   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |  370   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 
|  371 } |  371 } | 
|  372  |  372  | 
|  373 TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) { |  373 TEST_F(TcpCubicBytesSenderTest, RetransmissionDelay) { | 
|  374   const int64 kRttMs = 10; |  374   const int64_t kRttMs = 10; | 
|  375   const int64 kDeviationMs = 3; |  375   const int64_t kDeviationMs = 3; | 
|  376   EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); |  376   EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); | 
|  377  |  377  | 
|  378   sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs), |  378   sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs), | 
|  379                                 QuicTime::Delta::Zero(), clock_.Now()); |  379                                 QuicTime::Delta::Zero(), clock_.Now()); | 
|  380  |  380  | 
|  381   // Initial value is to set the median deviation to half of the initial rtt, |  381   // Initial value is to set the median deviation to half of the initial rtt, | 
|  382   // the median in then multiplied by a factor of 4 and finally the smoothed rtt |  382   // the median in then multiplied by a factor of 4 and finally the smoothed rtt | 
|  383   // is added which is the initial rtt. |  383   // is added which is the initial rtt. | 
|  384   QuicTime::Delta expected_delay = |  384   QuicTime::Delta expected_delay = | 
|  385       QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); |  385       QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); | 
|  386   EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); |  386   EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); | 
|  387  |  387  | 
|  388   for (int i = 0; i < 100; ++i) { |  388   for (int i = 0; i < 100; ++i) { | 
|  389     // Run to make sure that we converge. |  389     // Run to make sure that we converge. | 
|  390     sender_->rtt_stats_.UpdateRtt( |  390     sender_->rtt_stats_.UpdateRtt( | 
|  391         QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), |  391         QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs), | 
|  392         QuicTime::Delta::Zero(), clock_.Now()); |  392         QuicTime::Delta::Zero(), clock_.Now()); | 
|  393     sender_->rtt_stats_.UpdateRtt( |  393     sender_->rtt_stats_.UpdateRtt( | 
|  394         QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), |  394         QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs), | 
|  395         QuicTime::Delta::Zero(), clock_.Now()); |  395         QuicTime::Delta::Zero(), clock_.Now()); | 
|  396   } |  396   } | 
|  397   expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); |  397   expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); | 
|  398  |  398  | 
|  399   EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); |  399   EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1); | 
|  400   EXPECT_NEAR(expected_delay.ToMilliseconds(), |  400   EXPECT_NEAR(expected_delay.ToMilliseconds(), | 
|  401               sender_->RetransmissionDelay().ToMilliseconds(), 1); |  401               sender_->RetransmissionDelay().ToMilliseconds(), 1); | 
|  402   EXPECT_EQ( |  402   EXPECT_EQ(static_cast<int64_t>( | 
|  403       static_cast<int64>(sender_->GetCongestionWindow() * kNumMicrosPerSecond / |  403                 sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 
|  404                          sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), |  404                 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()), | 
|  405       sender_->BandwidthEstimate().ToBytesPerSecond()); |  405             sender_->BandwidthEstimate().ToBytesPerSecond()); | 
|  406 } |  406 } | 
|  407  |  407  | 
|  408 TEST_F(TcpCubicBytesSenderTest, TcpCubicResetEpochOnQuiescence) { |  408 TEST_F(TcpCubicBytesSenderTest, TcpCubicResetEpochOnQuiescence) { | 
|  409   const int kMaxCongestionWindow = 50; |  409   const int kMaxCongestionWindow = 50; | 
|  410   const QuicByteCount kMaxCongestionWindowBytes = |  410   const QuicByteCount kMaxCongestionWindowBytes = | 
|  411       kMaxCongestionWindow * kDefaultTCPMSS; |  411       kMaxCongestionWindow * kDefaultTCPMSS; | 
|  412   int num_sent = SendAvailableSendWindow(); |  412   int num_sent = SendAvailableSendWindow(); | 
|  413  |  413  | 
|  414   // Make sure we fall out of slow start. |  414   // Make sure we fall out of slow start. | 
|  415   QuicByteCount saved_cwnd = sender_->GetCongestionWindow(); |  415   QuicByteCount saved_cwnd = sender_->GetCongestionWindow(); | 
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  564   for (int i = 0; i < 10; ++i) { |  564   for (int i = 0; i < 10; ++i) { | 
|  565     // Send our full send window. |  565     // Send our full send window. | 
|  566     SendAvailableSendWindow(); |  566     SendAvailableSendWindow(); | 
|  567     EXPECT_TRUE(sender_->InRecovery()); |  567     EXPECT_TRUE(sender_->InRecovery()); | 
|  568     AckNPackets(2); |  568     AckNPackets(2); | 
|  569     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |  569     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 
|  570   } |  570   } | 
|  571   EXPECT_FALSE(sender_->InRecovery()); |  571   EXPECT_FALSE(sender_->InRecovery()); | 
|  572  |  572  | 
|  573   // Out of recovery now. Congestion window should not grow during RTT. |  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) { |  574   for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) { | 
|  575     // Send our full send window. |  575     // Send our full send window. | 
|  576     SendAvailableSendWindow(); |  576     SendAvailableSendWindow(); | 
|  577     AckNPackets(2); |  577     AckNPackets(2); | 
|  578     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |  578     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 
|  579   } |  579   } | 
|  580  |  580  | 
|  581   // Next ack should cause congestion window to grow by 1MSS. |  581   // Next ack should cause congestion window to grow by 1MSS. | 
|  582   SendAvailableSendWindow(); |  582   SendAvailableSendWindow(); | 
|  583   AckNPackets(2); |  583   AckNPackets(2); | 
|  584   expected_send_window += kDefaultTCPMSS; |  584   expected_send_window += kDefaultTCPMSS; | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  677   // Resets cwnd and slow start threshold on connection migrations. |  677   // Resets cwnd and slow start threshold on connection migrations. | 
|  678   sender_->OnConnectionMigration(); |  678   sender_->OnConnectionMigration(); | 
|  679   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |  679   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 
|  680   EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS, |  680   EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS, | 
|  681             sender_->GetSlowStartThreshold()); |  681             sender_->GetSlowStartThreshold()); | 
|  682   EXPECT_FALSE(sender_->hybrid_slow_start().started()); |  682   EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 
|  683 } |  683 } | 
|  684  |  684  | 
|  685 }  // namespace test |  685 }  // namespace test | 
|  686 }  // namespace net |  686 }  // namespace net | 
| OLD | NEW |