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 |