| 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 "net/quic/congestion_control/tcp_cubic_sender_packets.h" | 5 #include "net/quic/congestion_control/tcp_cubic_sender_packets.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 using std::min; | 22 using std::min; |
| 23 | 23 |
| 24 namespace net { | 24 namespace net { |
| 25 namespace test { | 25 namespace test { |
| 26 | 26 |
| 27 // TODO(ianswett): A number of theses tests were written with the assumption of | 27 // TODO(ianswett): A number of theses tests were written with the assumption of |
| 28 // an initial CWND of 10. They have carefully calculated values which should be | 28 // an initial CWND of 10. They have carefully calculated values which should be |
| 29 // updated to be based on kInitialCongestionWindow. | 29 // updated to be based on kInitialCongestionWindow. |
| 30 const uint32_t kInitialCongestionWindowPackets = 10; | 30 const uint32_t kInitialCongestionWindowPackets = 10; |
| 31 const uint32_t kMaxCongestionWindowPackets = 200; |
| 31 const uint32_t kDefaultWindowTCP = | 32 const uint32_t kDefaultWindowTCP = |
| 32 kInitialCongestionWindowPackets * kDefaultTCPMSS; | 33 kInitialCongestionWindowPackets * kDefaultTCPMSS; |
| 33 const float kRenoBeta = 0.7f; // Reno backoff factor. | 34 const float kRenoBeta = 0.7f; // Reno backoff factor. |
| 34 | 35 |
| 35 class TcpCubicSenderPacketsPeer : public TcpCubicSenderPackets { | 36 class TcpCubicSenderPacketsPeer : public TcpCubicSenderPackets { |
| 36 public: | 37 public: |
| 37 TcpCubicSenderPacketsPeer(const QuicClock* clock, | 38 TcpCubicSenderPacketsPeer(const QuicClock* clock, |
| 38 bool reno, | 39 bool reno, |
| 39 QuicPacketCount max_tcp_congestion_window) | 40 QuicPacketCount max_tcp_congestion_window) |
| 40 : TcpCubicSenderPackets(clock, | 41 : TcpCubicSenderPackets(clock, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 55 float GetRenoBeta() const { return RenoBeta(); } | 56 float GetRenoBeta() const { return RenoBeta(); } |
| 56 | 57 |
| 57 RttStats rtt_stats_; | 58 RttStats rtt_stats_; |
| 58 QuicConnectionStats stats_; | 59 QuicConnectionStats stats_; |
| 59 }; | 60 }; |
| 60 | 61 |
| 61 class TcpCubicSenderPacketsTest : public ::testing::Test { | 62 class TcpCubicSenderPacketsTest : public ::testing::Test { |
| 62 protected: | 63 protected: |
| 63 TcpCubicSenderPacketsTest() | 64 TcpCubicSenderPacketsTest() |
| 64 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 65 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
| 65 sender_( | 66 sender_(new TcpCubicSenderPacketsPeer(&clock_, |
| 66 new TcpCubicSenderPacketsPeer(&clock_, true, kMaxCongestionWindow)), | 67 true, |
| 68 kMaxCongestionWindowPackets)), |
| 67 packet_number_(1), | 69 packet_number_(1), |
| 68 acked_packet_number_(0), | 70 acked_packet_number_(0), |
| 69 bytes_in_flight_(0) {} | 71 bytes_in_flight_(0) {} |
| 70 | 72 |
| 71 int SendAvailableSendWindow() { | 73 int SendAvailableSendWindow() { |
| 72 return SendAvailableSendWindow(kDefaultTCPMSS); | 74 return SendAvailableSendWindow(kDefaultTCPMSS); |
| 73 } | 75 } |
| 74 | 76 |
| 75 int SendAvailableSendWindow(QuicPacketLength packet_length) { | 77 int SendAvailableSendWindow(QuicPacketLength packet_length) { |
| 76 // Send as long as TimeUntilSend returns Zero. | 78 // Send as long as TimeUntilSend returns Zero. |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 482 |
| 481 // Exit recovery and return to sending at the new rate. | 483 // Exit recovery and return to sending at the new rate. |
| 482 for (int i = 0; i < kNumberOfAcks; ++i) { | 484 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 483 AckNPackets(1); | 485 AckNPackets(1); |
| 484 EXPECT_EQ(1, SendAvailableSendWindow()); | 486 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 485 } | 487 } |
| 486 } | 488 } |
| 487 | 489 |
| 488 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindow) { | 490 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindow) { |
| 489 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 491 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 490 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold()); | 492 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold()); |
| 491 | 493 |
| 492 // Expect the window to decrease to the minimum once the RTO fires | 494 // Expect the window to decrease to the minimum once the RTO fires |
| 493 // and slow start threshold to be set to 1/2 of the CWND. | 495 // and slow start threshold to be set to 1/2 of the CWND. |
| 494 sender_->OnRetransmissionTimeout(true); | 496 sender_->OnRetransmissionTimeout(true); |
| 495 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); | 497 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow()); |
| 496 EXPECT_EQ(5u, sender_->slowstart_threshold()); | 498 EXPECT_EQ(5u, sender_->slowstart_threshold()); |
| 497 } | 499 } |
| 498 | 500 |
| 499 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindowNoRetransmission) { | 501 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindowNoRetransmission) { |
| 500 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 502 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 cached_network_params.set_min_rtt_ms(1000); | 874 cached_network_params.set_min_rtt_ms(1000); |
| 873 | 875 |
| 874 // Make sure that a bandwidth estimate results in a changed CWND. | 876 // Make sure that a bandwidth estimate results in a changed CWND. |
| 875 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() - | 877 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() - |
| 876 (kNumSecondsPerHour - 1)); | 878 (kNumSecondsPerHour - 1)); |
| 877 sender_->ResumeConnectionState(cached_network_params, false); | 879 sender_->ResumeConnectionState(cached_network_params, false); |
| 878 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window()); | 880 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window()); |
| 879 | 881 |
| 880 // Resumed CWND is limited to be in a sensible range. | 882 // Resumed CWND is limited to be in a sensible range. |
| 881 cached_network_params.set_bandwidth_estimate_bytes_per_second( | 883 cached_network_params.set_bandwidth_estimate_bytes_per_second( |
| 882 (kMaxCongestionWindow + 1) * kDefaultTCPMSS); | 884 (kMaxCongestionWindowPackets + 1) * kDefaultTCPMSS); |
| 883 sender_->ResumeConnectionState(cached_network_params, false); | 885 sender_->ResumeConnectionState(cached_network_params, false); |
| 884 EXPECT_EQ(kMaxCongestionWindow, sender_->congestion_window()); | 886 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->congestion_window()); |
| 885 | 887 |
| 886 if (FLAGS_quic_no_lower_bw_resumption_limit) { | 888 if (FLAGS_quic_no_lower_bw_resumption_limit) { |
| 887 // Resume with an illegal value of 0 and verify the server uses 1 instead. | 889 // Resume with an illegal value of 0 and verify the server uses 1 instead. |
| 888 cached_network_params.set_bandwidth_estimate_bytes_per_second(0); | 890 cached_network_params.set_bandwidth_estimate_bytes_per_second(0); |
| 889 sender_->ResumeConnectionState(cached_network_params, false); | 891 sender_->ResumeConnectionState(cached_network_params, false); |
| 890 EXPECT_EQ(sender_->min_congestion_window(), sender_->congestion_window()); | 892 EXPECT_EQ(sender_->min_congestion_window(), sender_->congestion_window()); |
| 891 } else { | 893 } else { |
| 892 cached_network_params.set_bandwidth_estimate_bytes_per_second( | 894 cached_network_params.set_bandwidth_estimate_bytes_per_second( |
| 893 (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS); | 895 (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS); |
| 894 sender_->ResumeConnectionState(cached_network_params, false); | 896 sender_->ResumeConnectionState(cached_network_params, false); |
| 895 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption, | 897 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption, |
| 896 sender_->congestion_window()); | 898 sender_->congestion_window()); |
| 897 } | 899 } |
| 898 | 900 |
| 899 // Resume to the max value. | 901 // Resume to the max value. |
| 900 cached_network_params.set_max_bandwidth_estimate_bytes_per_second( | 902 cached_network_params.set_max_bandwidth_estimate_bytes_per_second( |
| 901 kMaxCongestionWindow * kDefaultTCPMSS); | 903 kMaxCongestionWindowPackets * kDefaultTCPMSS); |
| 902 sender_->ResumeConnectionState(cached_network_params, true); | 904 sender_->ResumeConnectionState(cached_network_params, true); |
| 903 EXPECT_EQ(kMaxCongestionWindow * kDefaultTCPMSS, | 905 EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS, |
| 904 sender_->GetCongestionWindow()); | 906 sender_->GetCongestionWindow()); |
| 905 } | 907 } |
| 906 | 908 |
| 907 TEST_F(TcpCubicSenderPacketsTest, PaceBelowCWND) { | 909 TEST_F(TcpCubicSenderPacketsTest, PaceBelowCWND) { |
| 908 QuicConfig config; | 910 QuicConfig config; |
| 909 | 911 |
| 910 // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up | 912 // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up |
| 911 // to 4 to be sent. | 913 // to 4 to be sent. |
| 912 QuicTagVector options; | 914 QuicTagVector options; |
| 913 options.push_back(kMIN4); | 915 options.push_back(kMIN4); |
| 914 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); | 916 QuicConfigPeer::SetReceivedConnectionOptions(&config, options); |
| 915 sender_->SetFromConfig(config, Perspective::IS_SERVER); | 917 sender_->SetFromConfig(config, Perspective::IS_SERVER); |
| 916 sender_->OnRetransmissionTimeout(true); | 918 sender_->OnRetransmissionTimeout(true); |
| 917 EXPECT_EQ(1u, sender_->congestion_window()); | 919 EXPECT_EQ(1u, sender_->congestion_window()); |
| 918 EXPECT_TRUE( | 920 EXPECT_TRUE( |
| 919 sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero()); | 921 sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero()); |
| 920 EXPECT_TRUE( | 922 EXPECT_TRUE( |
| 921 sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS).IsZero()); | 923 sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS).IsZero()); |
| 922 EXPECT_TRUE( | 924 EXPECT_TRUE( |
| 923 sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS).IsZero()); | 925 sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS).IsZero()); |
| 924 EXPECT_FALSE( | 926 EXPECT_FALSE( |
| 925 sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS).IsZero()); | 927 sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS).IsZero()); |
| 926 } | 928 } |
| 927 | 929 |
| 928 TEST_F(TcpCubicSenderPacketsTest, ResetAfterConnectionMigration) { | 930 TEST_F(TcpCubicSenderPacketsTest, ResetAfterConnectionMigration) { |
| 929 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 931 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 930 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold()); | 932 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold()); |
| 931 | 933 |
| 932 // Starts with slow start. | 934 // Starts with slow start. |
| 933 sender_->SetNumEmulatedConnections(1); | 935 sender_->SetNumEmulatedConnections(1); |
| 934 const int kNumberOfAcks = 10; | 936 const int kNumberOfAcks = 10; |
| 935 for (int i = 0; i < kNumberOfAcks; ++i) { | 937 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 936 // Send our full send window. | 938 // Send our full send window. |
| 937 SendAvailableSendWindow(); | 939 SendAvailableSendWindow(); |
| 938 AckNPackets(2); | 940 AckNPackets(2); |
| 939 } | 941 } |
| 940 SendAvailableSendWindow(); | 942 SendAvailableSendWindow(); |
| 941 QuicByteCount expected_send_window = | 943 QuicByteCount expected_send_window = |
| 942 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); | 944 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 943 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 945 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 944 | 946 |
| 945 // Loses a packet to exit slow start. | 947 // Loses a packet to exit slow start. |
| 946 LoseNPackets(1); | 948 LoseNPackets(1); |
| 947 | 949 |
| 948 // We should now have fallen out of slow start with a reduced window. Slow | 950 // We should now have fallen out of slow start with a reduced window. Slow |
| 949 // start threshold is also updated. | 951 // start threshold is also updated. |
| 950 expected_send_window *= kRenoBeta; | 952 expected_send_window *= kRenoBeta; |
| 951 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 953 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 952 EXPECT_EQ(expected_send_window / kDefaultTCPMSS, | 954 EXPECT_EQ(expected_send_window / kDefaultTCPMSS, |
| 953 sender_->slowstart_threshold()); | 955 sender_->slowstart_threshold()); |
| 954 | 956 |
| 955 // Resets cwnd and slow start threshold on connection migrations. | 957 // Resets cwnd and slow start threshold on connection migrations. |
| 956 sender_->OnConnectionMigration(); | 958 sender_->OnConnectionMigration(); |
| 957 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 959 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 958 EXPECT_EQ(kMaxCongestionWindow, sender_->slowstart_threshold()); | 960 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold()); |
| 959 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 961 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
| 960 } | 962 } |
| 961 | 963 |
| 962 } // namespace test | 964 } // namespace test |
| 963 } // namespace net | 965 } // namespace net |
| OLD | NEW |