| 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" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; | 22 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; |
| 23 | 23 |
| 24 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 24 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
| 25 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; | 25 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; |
| 26 | 26 |
| 27 class TcpCubicSenderPeer : public TcpCubicSender { | 27 class TcpCubicSenderPeer : public TcpCubicSender { |
| 28 public: | 28 public: |
| 29 TcpCubicSenderPeer(const QuicClock* clock, | 29 TcpCubicSenderPeer(const QuicClock* clock, |
| 30 bool reno, | 30 bool reno, |
| 31 QuicTcpCongestionWindow max_tcp_congestion_window) | 31 QuicTcpCongestionWindow max_tcp_congestion_window) |
| 32 : TcpCubicSender( | 32 : TcpCubicSender(clock, |
| 33 clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) { | 33 &rtt_stats_, |
| 34 } | 34 reno, |
| 35 max_tcp_congestion_window, |
| 36 &stats_) {} |
| 35 | 37 |
| 36 QuicTcpCongestionWindow congestion_window() { | 38 QuicTcpCongestionWindow congestion_window() { return congestion_window_; } |
| 37 return congestion_window_; | |
| 38 } | |
| 39 | 39 |
| 40 const HybridSlowStart& hybrid_slow_start() const { | 40 const HybridSlowStart& hybrid_slow_start() const { |
| 41 return hybrid_slow_start_; | 41 return hybrid_slow_start_; |
| 42 } | 42 } |
| 43 | 43 |
| 44 RttStats rtt_stats_; | 44 RttStats rtt_stats_; |
| 45 QuicConnectionStats stats_; | 45 QuicConnectionStats stats_; |
| 46 | 46 |
| 47 using TcpCubicSender::AvailableSendWindow; | 47 using TcpCubicSender::AvailableSendWindow; |
| 48 using TcpCubicSender::SendWindow; | 48 using TcpCubicSender::SendWindow; |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 class TcpCubicSenderTest : public ::testing::Test { | 51 class TcpCubicSenderTest : public ::testing::Test { |
| 52 protected: | 52 protected: |
| 53 TcpCubicSenderTest() | 53 TcpCubicSenderTest() |
| 54 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 54 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
| 55 sender_(new TcpCubicSenderPeer(&clock_, true, | 55 sender_(new TcpCubicSenderPeer(&clock_, |
| 56 true, |
| 56 kDefaultMaxCongestionWindowTCP)), | 57 kDefaultMaxCongestionWindowTCP)), |
| 57 receiver_(new TcpReceiver()), | 58 receiver_(new TcpReceiver()), |
| 58 sequence_number_(1), | 59 sequence_number_(1), |
| 59 acked_sequence_number_(0) { | 60 acked_sequence_number_(0) {} |
| 60 } | |
| 61 | 61 |
| 62 int SendAvailableSendWindow() { | 62 int SendAvailableSendWindow() { |
| 63 // Send as long as TimeUntilSend returns Zero. | 63 // Send as long as TimeUntilSend returns Zero. |
| 64 int packets_sent = 0; | 64 int packets_sent = 0; |
| 65 bool can_send = sender_->TimeUntilSend( | 65 bool can_send = |
| 66 clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero(); | 66 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero(); |
| 67 while (can_send) { | 67 while (can_send) { |
| 68 sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS, | 68 sender_->OnPacketSent(clock_.Now(), |
| 69 sequence_number_++, |
| 70 kDefaultTCPMSS, |
| 69 HAS_RETRANSMITTABLE_DATA); | 71 HAS_RETRANSMITTABLE_DATA); |
| 70 ++packets_sent; | 72 ++packets_sent; |
| 71 can_send = sender_->TimeUntilSend( | 73 can_send = sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA) |
| 72 clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero(); | 74 .IsZero(); |
| 73 } | 75 } |
| 74 return packets_sent; | 76 return packets_sent; |
| 75 } | 77 } |
| 76 | 78 |
| 77 void UpdateRtt(QuicTime::Delta rtt) { | 79 void UpdateRtt(QuicTime::Delta rtt) { |
| 78 sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now()); | 80 sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now()); |
| 79 sender_->OnRttUpdated(acked_sequence_number_ + 1); | 81 sender_->OnRttUpdated(acked_sequence_number_ + 1); |
| 80 } | 82 } |
| 81 | 83 |
| 82 // Normal is that TCP acks every other segment. | 84 // Normal is that TCP acks every other segment. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 104 QuicPacketSequenceNumber sequence_number_; | 106 QuicPacketSequenceNumber sequence_number_; |
| 105 QuicPacketSequenceNumber acked_sequence_number_; | 107 QuicPacketSequenceNumber acked_sequence_number_; |
| 106 }; | 108 }; |
| 107 | 109 |
| 108 TEST_F(TcpCubicSenderTest, SimpleSender) { | 110 TEST_F(TcpCubicSenderTest, SimpleSender) { |
| 109 QuicCongestionFeedbackFrame feedback; | 111 QuicCongestionFeedbackFrame feedback; |
| 110 // At startup make sure we are at the default. | 112 // At startup make sure we are at the default. |
| 111 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); | 113 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); |
| 112 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 114 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 113 // At startup make sure we can send. | 115 // At startup make sure we can send. |
| 114 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 116 EXPECT_TRUE( |
| 115 HAS_RETRANSMITTABLE_DATA).IsZero()); | 117 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 116 // Get default QuicCongestionFeedbackFrame from receiver. | 118 // Get default QuicCongestionFeedbackFrame from receiver. |
| 117 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 119 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 118 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 120 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 119 // Make sure we can send. | 121 // Make sure we can send. |
| 120 | 122 |
| 121 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 123 EXPECT_TRUE( |
| 122 HAS_RETRANSMITTABLE_DATA).IsZero()); | 124 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 123 // And that window is un-affected. | 125 // And that window is un-affected. |
| 124 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); | 126 EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); |
| 125 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); | 127 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); |
| 126 | 128 |
| 127 // There is available window, so we should be able to send. | 129 // There is available window, so we should be able to send. |
| 128 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 130 EXPECT_TRUE( |
| 129 HAS_RETRANSMITTABLE_DATA).IsZero()); | 131 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 130 | 132 |
| 131 // Fill the send window with data, then verify that we can't send. | 133 // Fill the send window with data, then verify that we can't send. |
| 132 SendAvailableSendWindow(); | 134 SendAvailableSendWindow(); |
| 133 EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(), | 135 EXPECT_FALSE( |
| 134 HAS_RETRANSMITTABLE_DATA).IsZero()); | 136 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 135 } | 137 } |
| 136 | 138 |
| 137 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { | 139 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { |
| 138 const int kNumberOfAcks = 20; | 140 const int kNumberOfAcks = 20; |
| 139 QuicCongestionFeedbackFrame feedback; | 141 QuicCongestionFeedbackFrame feedback; |
| 140 // At startup make sure we can send. | 142 // At startup make sure we can send. |
| 141 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 143 EXPECT_TRUE( |
| 142 HAS_RETRANSMITTABLE_DATA).IsZero()); | 144 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 143 // Get default QuicCongestionFeedbackFrame from receiver. | 145 // Get default QuicCongestionFeedbackFrame from receiver. |
| 144 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 146 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 145 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 147 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 146 // Make sure we can send. | 148 // Make sure we can send. |
| 147 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 149 EXPECT_TRUE( |
| 148 HAS_RETRANSMITTABLE_DATA).IsZero()); | 150 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 149 | 151 |
| 150 for (int i = 0; i < kNumberOfAcks; ++i) { | 152 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 151 // Send our full send window. | 153 // Send our full send window. |
| 152 SendAvailableSendWindow(); | 154 SendAvailableSendWindow(); |
| 153 AckNPackets(2); | 155 AckNPackets(2); |
| 154 } | 156 } |
| 155 QuicByteCount bytes_to_send = sender_->SendWindow(); | 157 QuicByteCount bytes_to_send = sender_->SendWindow(); |
| 156 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, | 158 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, |
| 157 bytes_to_send); | 159 bytes_to_send); |
| 158 } | 160 } |
| 159 | 161 |
| 160 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { | 162 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { |
| 161 // Make sure that we fall out of slow start when we send ACK train longer | 163 // Make sure that we fall out of slow start when we send ACK train longer |
| 162 // than half the RTT, in this test case 30ms, which is more than 30 calls to | 164 // than half the RTT, in this test case 30ms, which is more than 30 calls to |
| 163 // Ack2Packets in one round. | 165 // Ack2Packets in one round. |
| 164 // Since we start at 10 packet first round will be 5 second round 10 etc | 166 // Since we start at 10 packet first round will be 5 second round 10 etc |
| 165 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 | 167 // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 |
| 166 const int kNumberOfAcks = 65; | 168 const int kNumberOfAcks = 65; |
| 167 QuicCongestionFeedbackFrame feedback; | 169 QuicCongestionFeedbackFrame feedback; |
| 168 // At startup make sure we can send. | 170 // At startup make sure we can send. |
| 169 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 171 EXPECT_TRUE( |
| 170 HAS_RETRANSMITTABLE_DATA).IsZero()); | 172 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 171 // Get default QuicCongestionFeedbackFrame from receiver. | 173 // Get default QuicCongestionFeedbackFrame from receiver. |
| 172 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 174 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 173 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 175 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 174 // Make sure we can send. | 176 // Make sure we can send. |
| 175 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 177 EXPECT_TRUE( |
| 176 HAS_RETRANSMITTABLE_DATA).IsZero()); | 178 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 177 | 179 |
| 178 for (int i = 0; i < kNumberOfAcks; ++i) { | 180 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 179 // Send our full send window. | 181 // Send our full send window. |
| 180 SendAvailableSendWindow(); | 182 SendAvailableSendWindow(); |
| 181 AckNPackets(2); | 183 AckNPackets(2); |
| 182 } | 184 } |
| 183 QuicByteCount expected_send_window = | 185 QuicByteCount expected_send_window = |
| 184 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); | 186 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 185 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 187 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 186 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 188 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 202 // Now RTO and ensure slow start gets reset. | 204 // Now RTO and ensure slow start gets reset. |
| 203 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 205 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
| 204 sender_->OnRetransmissionTimeout(true); | 206 sender_->OnRetransmissionTimeout(true); |
| 205 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 207 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
| 206 } | 208 } |
| 207 | 209 |
| 208 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { | 210 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { |
| 209 // Make sure that we fall out of slow start when we encounter a packet loss. | 211 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 210 QuicCongestionFeedbackFrame feedback; | 212 QuicCongestionFeedbackFrame feedback; |
| 211 // At startup make sure we can send. | 213 // At startup make sure we can send. |
| 212 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 214 EXPECT_TRUE( |
| 213 HAS_RETRANSMITTABLE_DATA).IsZero()); | 215 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 214 // Get default QuicCongestionFeedbackFrame from receiver. | 216 // Get default QuicCongestionFeedbackFrame from receiver. |
| 215 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 217 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 216 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 218 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 217 // Make sure we can send. | 219 // Make sure we can send. |
| 218 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 220 EXPECT_TRUE( |
| 219 HAS_RETRANSMITTABLE_DATA).IsZero()); | 221 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 220 | 222 |
| 221 const int kNumberOfAcks = 10; | 223 const int kNumberOfAcks = 10; |
| 222 for (int i = 0; i < kNumberOfAcks; ++i) { | 224 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 223 // Send our full send window. | 225 // Send our full send window. |
| 224 SendAvailableSendWindow(); | 226 SendAvailableSendWindow(); |
| 225 AckNPackets(2); | 227 AckNPackets(2); |
| 226 } | 228 } |
| 227 SendAvailableSendWindow(); | 229 SendAvailableSendWindow(); |
| 228 QuicByteCount expected_send_window = kDefaultWindowTCP + | 230 QuicByteCount expected_send_window = |
| 229 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 231 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 230 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 232 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 231 | 233 |
| 232 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); | 234 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); |
| 233 ++acked_sequence_number_; | 235 ++acked_sequence_number_; |
| 234 | 236 |
| 235 // Make sure that we can send right now due to limited transmit. | 237 // Make sure that we can send right now due to limited transmit. |
| 236 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 238 EXPECT_TRUE( |
| 237 HAS_RETRANSMITTABLE_DATA).IsZero()); | 239 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 238 | 240 |
| 239 // We should now have fallen out of slow start. | 241 // We should now have fallen out of slow start. |
| 240 // We expect window to be cut in half by Reno. | 242 // We expect window to be cut in half by Reno. |
| 241 expected_send_window /= 2; | 243 expected_send_window /= 2; |
| 242 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 244 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 243 | 245 |
| 244 // Testing Reno phase. | 246 // Testing Reno phase. |
| 245 // We need to ack half of the pending packet before we can send again. | 247 // We need to ack half of the pending packet before we can send again. |
| 246 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 248 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
| 247 AckNPackets(number_of_packets_in_window); | 249 AckNPackets(number_of_packets_in_window); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 270 EXPECT_TRUE(sender_->hybrid_slow_start().started()); | 272 EXPECT_TRUE(sender_->hybrid_slow_start().started()); |
| 271 sender_->OnRetransmissionTimeout(true); | 273 sender_->OnRetransmissionTimeout(true); |
| 272 EXPECT_FALSE(sender_->hybrid_slow_start().started()); | 274 EXPECT_FALSE(sender_->hybrid_slow_start().started()); |
| 273 } | 275 } |
| 274 | 276 |
| 275 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) { | 277 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) { |
| 276 // Test based on the first example in RFC6937. | 278 // Test based on the first example in RFC6937. |
| 277 // Make sure that we fall out of slow start when we encounter a packet loss. | 279 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 278 QuicCongestionFeedbackFrame feedback; | 280 QuicCongestionFeedbackFrame feedback; |
| 279 // At startup make sure we can send. | 281 // At startup make sure we can send. |
| 280 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 282 EXPECT_TRUE( |
| 281 HAS_RETRANSMITTABLE_DATA).IsZero()); | 283 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 282 // Get default QuicCongestionFeedbackFrame from receiver. | 284 // Get default QuicCongestionFeedbackFrame from receiver. |
| 283 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 285 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 284 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 286 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 285 | 287 |
| 286 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 288 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. |
| 287 const int kNumberOfAcks = 5; | 289 const int kNumberOfAcks = 5; |
| 288 for (int i = 0; i < kNumberOfAcks; ++i) { | 290 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 289 // Send our full send window. | 291 // Send our full send window. |
| 290 SendAvailableSendWindow(); | 292 SendAvailableSendWindow(); |
| 291 AckNPackets(2); | 293 AckNPackets(2); |
| 292 } | 294 } |
| 293 SendAvailableSendWindow(); | 295 SendAvailableSendWindow(); |
| 294 QuicByteCount expected_send_window = kDefaultWindowTCP + | 296 QuicByteCount expected_send_window = |
| 295 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 297 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 296 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 298 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 297 | 299 |
| 298 LoseNPackets(1); | 300 LoseNPackets(1); |
| 299 | 301 |
| 300 // We should now have fallen out of slow start. | 302 // We should now have fallen out of slow start. |
| 301 // We expect window to be cut in half by Reno. | 303 // We expect window to be cut in half by Reno. |
| 302 expected_send_window /= 2; | 304 expected_send_window /= 2; |
| 303 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 305 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 304 | 306 |
| 305 // Send 1 packet to simulate limited transmit. | 307 // Send 1 packet to simulate limited transmit. |
| 306 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 308 EXPECT_TRUE( |
| 307 HAS_RETRANSMITTABLE_DATA).IsZero()); | 309 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 308 EXPECT_EQ(1, SendAvailableSendWindow()); | 310 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 309 | 311 |
| 310 // Testing TCP proportional rate reduction. | 312 // Testing TCP proportional rate reduction. |
| 311 // We should send one packet for every two received acks over the remaining | 313 // We should send one packet for every two received acks over the remaining |
| 312 // 18 outstanding packets. | 314 // 18 outstanding packets. |
| 313 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; | 315 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; |
| 314 // The number of packets before we exit recovery is the original CWND minus | 316 // The number of packets before we exit recovery is the original CWND minus |
| 315 // the packet that has been lost and the one which triggered the loss. | 317 // the packet that has been lost and the one which triggered the loss. |
| 316 size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1; | 318 size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1; |
| 317 for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) { | 319 for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) { |
| 318 AckNPackets(2); | 320 AckNPackets(2); |
| 319 EXPECT_TRUE(sender_->TimeUntilSend( | 321 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA) |
| 320 clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); | 322 .IsZero()); |
| 321 EXPECT_EQ(0u, sender_->AvailableSendWindow()); | 323 EXPECT_EQ(0u, sender_->AvailableSendWindow()); |
| 322 EXPECT_EQ(1, SendAvailableSendWindow()); | 324 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 323 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 325 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 324 } | 326 } |
| 325 // If there is one more packet to ack before completing recovery, ack it. | 327 // If there is one more packet to ack before completing recovery, ack it. |
| 326 if (remaining_packets_in_recovery % 2 == 1) { | 328 if (remaining_packets_in_recovery % 2 == 1) { |
| 327 AckNPackets(1); | 329 AckNPackets(1); |
| 328 } | 330 } |
| 329 | 331 |
| 330 // We need to ack another window before we increase CWND by 1. | 332 // We need to ack another window before we increase CWND by 1. |
| 331 for (size_t i = 0; i < number_of_packets_in_window - 1; ++i) { | 333 for (size_t i = 0; i < number_of_packets_in_window - 1; ++i) { |
| 332 AckNPackets(1); | 334 AckNPackets(1); |
| 333 EXPECT_EQ(1, SendAvailableSendWindow()); | 335 EXPECT_EQ(1, SendAvailableSendWindow()); |
| 334 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 336 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 335 } | 337 } |
| 336 | 338 |
| 337 AckNPackets(1); | 339 AckNPackets(1); |
| 338 expected_send_window += kDefaultTCPMSS; | 340 expected_send_window += kDefaultTCPMSS; |
| 339 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 341 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 340 } | 342 } |
| 341 | 343 |
| 342 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { | 344 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) { |
| 343 // Test based on the second example in RFC6937, though we also implement | 345 // Test based on the second example in RFC6937, though we also implement |
| 344 // forward acknowledgements, so the first two incoming acks will trigger | 346 // forward acknowledgements, so the first two incoming acks will trigger |
| 345 // PRR immediately. | 347 // PRR immediately. |
| 346 // Make sure that we fall out of slow start when we encounter a packet loss. | 348 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 347 QuicCongestionFeedbackFrame feedback; | 349 QuicCongestionFeedbackFrame feedback; |
| 348 // At startup make sure we can send. | 350 // At startup make sure we can send. |
| 349 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 351 EXPECT_TRUE( |
| 350 HAS_RETRANSMITTABLE_DATA).IsZero()); | 352 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 351 // Get default QuicCongestionFeedbackFrame from receiver. | 353 // Get default QuicCongestionFeedbackFrame from receiver. |
| 352 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 354 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 353 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 355 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 354 | 356 |
| 355 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. | 357 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example. |
| 356 const int kNumberOfAcks = 5; | 358 const int kNumberOfAcks = 5; |
| 357 for (int i = 0; i < kNumberOfAcks; ++i) { | 359 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 358 // Send our full send window. | 360 // Send our full send window. |
| 359 SendAvailableSendWindow(); | 361 SendAvailableSendWindow(); |
| 360 AckNPackets(2); | 362 AckNPackets(2); |
| 361 } | 363 } |
| 362 SendAvailableSendWindow(); | 364 SendAvailableSendWindow(); |
| 363 QuicByteCount expected_send_window = kDefaultWindowTCP + | 365 QuicByteCount expected_send_window = |
| 364 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 366 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 365 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 367 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 366 | 368 |
| 367 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK. | 369 // Ack a packet with a 15 packet gap, losing 13 of them due to FACK. |
| 368 sender_->OnPacketAcked(acked_sequence_number_ + 15, kDefaultTCPMSS); | 370 sender_->OnPacketAcked(acked_sequence_number_ + 15, kDefaultTCPMSS); |
| 369 LoseNPackets(13); | 371 LoseNPackets(13); |
| 370 | 372 |
| 371 // We should now have fallen out of slow start. | 373 // We should now have fallen out of slow start. |
| 372 // We expect window to be cut in half by Reno. | 374 // We expect window to be cut in half by Reno. |
| 373 expected_send_window /= 2; | 375 expected_send_window /= 2; |
| 374 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 376 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 // Run to make sure that we converge. | 443 // Run to make sure that we converge. |
| 442 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); | 444 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); |
| 443 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); | 445 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); |
| 444 } | 446 } |
| 445 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); | 447 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); |
| 446 | 448 |
| 447 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1); | 449 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1); |
| 448 EXPECT_NEAR(expected_delay.ToMilliseconds(), | 450 EXPECT_NEAR(expected_delay.ToMilliseconds(), |
| 449 sender_->RetransmissionDelay().ToMilliseconds(), | 451 sender_->RetransmissionDelay().ToMilliseconds(), |
| 450 1); | 452 1); |
| 451 EXPECT_EQ(static_cast<int64>( | 453 EXPECT_EQ( |
| 452 sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 454 static_cast<int64>(sender_->GetCongestionWindow() * kNumMicrosPerSecond / |
| 453 sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()), | 455 sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()), |
| 454 sender_->BandwidthEstimate().ToBytesPerSecond()); | 456 sender_->BandwidthEstimate().ToBytesPerSecond()); |
| 455 } | 457 } |
| 456 | 458 |
| 457 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { | 459 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { |
| 458 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; | 460 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; |
| 459 const int kNumberOfAcks = 100; | 461 const int kNumberOfAcks = 100; |
| 460 sender_.reset( | 462 sender_.reset( |
| 461 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | 463 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); |
| 462 | 464 |
| 463 QuicCongestionFeedbackFrame feedback; | 465 QuicCongestionFeedbackFrame feedback; |
| 464 // At startup make sure we can send. | 466 // At startup make sure we can send. |
| 465 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 467 EXPECT_TRUE( |
| 466 HAS_RETRANSMITTABLE_DATA).IsZero()); | 468 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 467 // Get default QuicCongestionFeedbackFrame from receiver. | 469 // Get default QuicCongestionFeedbackFrame from receiver. |
| 468 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 470 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 469 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 471 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 470 // Make sure we can send. | 472 // Make sure we can send. |
| 471 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 473 EXPECT_TRUE( |
| 472 HAS_RETRANSMITTABLE_DATA).IsZero()); | 474 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 473 | 475 |
| 474 for (int i = 0; i < kNumberOfAcks; ++i) { | 476 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 475 // Send our full send window. | 477 // Send our full send window. |
| 476 SendAvailableSendWindow(); | 478 SendAvailableSendWindow(); |
| 477 AckNPackets(2); | 479 AckNPackets(2); |
| 478 } | 480 } |
| 479 QuicByteCount expected_send_window = | 481 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS; |
| 480 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
| 481 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 482 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 482 } | 483 } |
| 483 | 484 |
| 484 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { | 485 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { |
| 485 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; | 486 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; |
| 486 const int kNumberOfAcks = 1000; | 487 const int kNumberOfAcks = 1000; |
| 487 sender_.reset( | 488 sender_.reset(new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP)); |
| 488 new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP)); | |
| 489 | 489 |
| 490 QuicCongestionFeedbackFrame feedback; | 490 QuicCongestionFeedbackFrame feedback; |
| 491 // At startup make sure we can send. | 491 // At startup make sure we can send. |
| 492 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 492 EXPECT_TRUE( |
| 493 HAS_RETRANSMITTABLE_DATA).IsZero()); | 493 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 494 // Get default QuicCongestionFeedbackFrame from receiver. | 494 // Get default QuicCongestionFeedbackFrame from receiver. |
| 495 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 495 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 496 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 496 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 497 // Make sure we can send. | 497 // Make sure we can send. |
| 498 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 498 EXPECT_TRUE( |
| 499 HAS_RETRANSMITTABLE_DATA).IsZero()); | 499 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 500 | |
| 501 | 500 |
| 502 SendAvailableSendWindow(); | 501 SendAvailableSendWindow(); |
| 503 AckNPackets(2); | 502 AckNPackets(2); |
| 504 // Make sure we fall out of slow start. | 503 // Make sure we fall out of slow start. |
| 505 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); | 504 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); |
| 506 | 505 |
| 507 for (int i = 0; i < kNumberOfAcks; ++i) { | 506 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 508 // Send our full send window. | 507 // Send our full send window. |
| 509 SendAvailableSendWindow(); | 508 SendAvailableSendWindow(); |
| 510 AckNPackets(2); | 509 AckNPackets(2); |
| 511 } | 510 } |
| 512 | 511 |
| 513 QuicByteCount expected_send_window = | 512 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS; |
| 514 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
| 515 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 513 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 516 } | 514 } |
| 517 | 515 |
| 518 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { | 516 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { |
| 519 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; | 517 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; |
| 520 // Set to 10000 to compensate for small cubic alpha. | 518 // Set to 10000 to compensate for small cubic alpha. |
| 521 const int kNumberOfAcks = 10000; | 519 const int kNumberOfAcks = 10000; |
| 522 | 520 |
| 523 sender_.reset( | 521 sender_.reset( |
| 524 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | 522 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); |
| 525 | 523 |
| 526 QuicCongestionFeedbackFrame feedback; | 524 QuicCongestionFeedbackFrame feedback; |
| 527 // At startup make sure we can send. | 525 // At startup make sure we can send. |
| 528 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 526 EXPECT_TRUE( |
| 529 HAS_RETRANSMITTABLE_DATA).IsZero()); | 527 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 530 // Get default QuicCongestionFeedbackFrame from receiver. | 528 // Get default QuicCongestionFeedbackFrame from receiver. |
| 531 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 529 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 532 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 530 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 533 // Make sure we can send. | 531 // Make sure we can send. |
| 534 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 532 EXPECT_TRUE( |
| 535 HAS_RETRANSMITTABLE_DATA).IsZero()); | 533 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 536 | 534 |
| 537 SendAvailableSendWindow(); | 535 SendAvailableSendWindow(); |
| 538 AckNPackets(2); | 536 AckNPackets(2); |
| 539 // Make sure we fall out of slow start. | 537 // Make sure we fall out of slow start. |
| 540 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); | 538 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); |
| 541 | 539 |
| 542 for (int i = 0; i < kNumberOfAcks; ++i) { | 540 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 543 // Send our full send window. | 541 // Send our full send window. |
| 544 SendAvailableSendWindow(); | 542 SendAvailableSendWindow(); |
| 545 AckNPackets(2); | 543 AckNPackets(2); |
| 546 } | 544 } |
| 547 | 545 |
| 548 QuicByteCount expected_send_window = | 546 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS; |
| 549 kMaxCongestionWindowTCP * kDefaultTCPMSS; | |
| 550 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 547 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 551 } | 548 } |
| 552 | 549 |
| 553 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { | 550 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { |
| 554 SendAvailableSendWindow(); | 551 SendAvailableSendWindow(); |
| 555 const QuicByteCount initial_window = sender_->GetCongestionWindow(); | 552 const QuicByteCount initial_window = sender_->GetCongestionWindow(); |
| 556 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); | 553 sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); |
| 557 const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); | 554 const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); |
| 558 EXPECT_GT(initial_window, post_loss_window); | 555 EXPECT_GT(initial_window, post_loss_window); |
| 559 sender_->OnPacketLost(acked_sequence_number_ + 3, clock_.Now()); | 556 sender_->OnPacketLost(acked_sequence_number_ + 3, clock_.Now()); |
| 560 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); | 557 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); |
| 561 sender_->OnPacketLost(sequence_number_ - 1, clock_.Now()); | 558 sender_->OnPacketLost(sequence_number_ - 1, clock_.Now()); |
| 562 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); | 559 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); |
| 563 | 560 |
| 564 // Lose a later packet and ensure the window decreases. | 561 // Lose a later packet and ensure the window decreases. |
| 565 sender_->OnPacketLost(sequence_number_, clock_.Now()); | 562 sender_->OnPacketLost(sequence_number_, clock_.Now()); |
| 566 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow()); | 563 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow()); |
| 567 } | 564 } |
| 568 | 565 |
| 569 TEST_F(TcpCubicSenderTest, SendWindowNotAffectedByAcks) { | 566 TEST_F(TcpCubicSenderTest, SendWindowNotAffectedByAcks) { |
| 570 QuicByteCount send_window = sender_->AvailableSendWindow(); | 567 QuicByteCount send_window = sender_->AvailableSendWindow(); |
| 571 | 568 |
| 572 // Send a packet with no retransmittable data, and ensure that the congestion | 569 // Send a packet with no retransmittable data, and ensure that the congestion |
| 573 // window doesn't change. | 570 // window doesn't change. |
| 574 QuicByteCount bytes_in_packet = min(kDefaultTCPMSS, send_window); | 571 QuicByteCount bytes_in_packet = min(kDefaultTCPMSS, send_window); |
| 575 sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet, | 572 sender_->OnPacketSent(clock_.Now(), |
| 573 sequence_number_++, |
| 574 bytes_in_packet, |
| 576 NO_RETRANSMITTABLE_DATA); | 575 NO_RETRANSMITTABLE_DATA); |
| 577 EXPECT_EQ(send_window, sender_->AvailableSendWindow()); | 576 EXPECT_EQ(send_window, sender_->AvailableSendWindow()); |
| 578 | 577 |
| 579 // Send a data packet with retransmittable data, and ensure that the | 578 // Send a data packet with retransmittable data, and ensure that the |
| 580 // congestion window has shrunk. | 579 // congestion window has shrunk. |
| 581 sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet, | 580 sender_->OnPacketSent(clock_.Now(), |
| 581 sequence_number_++, |
| 582 bytes_in_packet, |
| 582 HAS_RETRANSMITTABLE_DATA); | 583 HAS_RETRANSMITTABLE_DATA); |
| 583 EXPECT_GT(send_window, sender_->AvailableSendWindow()); | 584 EXPECT_GT(send_window, sender_->AvailableSendWindow()); |
| 584 } | 585 } |
| 585 | 586 |
| 586 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { | 587 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { |
| 587 QuicTcpCongestionWindow congestion_window = sender_->congestion_window(); | 588 QuicTcpCongestionWindow congestion_window = sender_->congestion_window(); |
| 588 QuicConfig config; | 589 QuicConfig config; |
| 589 QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window); | 590 QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window); |
| 590 | 591 |
| 591 sender_->SetFromConfig(config, true); | 592 sender_->SetFromConfig(config, true); |
| 592 EXPECT_EQ(2 * congestion_window, sender_->congestion_window()); | 593 EXPECT_EQ(2 * congestion_window, sender_->congestion_window()); |
| 593 } | 594 } |
| 594 | 595 |
| 595 TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) { | 596 TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) { |
| 596 // Make sure that we fall out of slow start when we encounter a packet loss. | 597 // Make sure that we fall out of slow start when we encounter a packet loss. |
| 597 QuicCongestionFeedbackFrame feedback; | 598 QuicCongestionFeedbackFrame feedback; |
| 598 // At startup make sure we can send. | 599 // At startup make sure we can send. |
| 599 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), | 600 EXPECT_TRUE( |
| 600 HAS_RETRANSMITTABLE_DATA).IsZero()); | 601 sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero()); |
| 601 // Get default QuicCongestionFeedbackFrame from receiver. | 602 // Get default QuicCongestionFeedbackFrame from receiver. |
| 602 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); | 603 ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); |
| 603 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); | 604 sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); |
| 604 // Ack 10 packets in 5 acks to raise the CWND to 20. | 605 // Ack 10 packets in 5 acks to raise the CWND to 20. |
| 605 const int kNumberOfAcks = 5; | 606 const int kNumberOfAcks = 5; |
| 606 for (int i = 0; i < kNumberOfAcks; ++i) { | 607 for (int i = 0; i < kNumberOfAcks; ++i) { |
| 607 // Send our full send window. | 608 // Send our full send window. |
| 608 SendAvailableSendWindow(); | 609 SendAvailableSendWindow(); |
| 609 AckNPackets(2); | 610 AckNPackets(2); |
| 610 } | 611 } |
| 611 SendAvailableSendWindow(); | 612 SendAvailableSendWindow(); |
| 612 QuicByteCount expected_send_window = kDefaultWindowTCP + | 613 QuicByteCount expected_send_window = |
| 613 (kDefaultTCPMSS * 2 * kNumberOfAcks); | 614 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks); |
| 614 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 615 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 615 | 616 |
| 616 LoseNPackets(1); | 617 LoseNPackets(1); |
| 617 | 618 |
| 618 // We should now have fallen out of slow start, and window should be cut in | 619 // We should now have fallen out of slow start, and window should be cut in |
| 619 // half by Reno. New cwnd should be 10. | 620 // half by Reno. New cwnd should be 10. |
| 620 expected_send_window /= 2; | 621 expected_send_window /= 2; |
| 621 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 622 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 622 | 623 |
| 623 // No congestion window growth should occur in recovery phase, i.e., | 624 // No congestion window growth should occur in recovery phase, i.e., |
| (...skipping 14 matching lines...) Expand all Loading... |
| 638 } | 639 } |
| 639 | 640 |
| 640 // Next ack should cause congestion window to grow by 1MSS. | 641 // Next ack should cause congestion window to grow by 1MSS. |
| 641 AckNPackets(2); | 642 AckNPackets(2); |
| 642 expected_send_window += kDefaultTCPMSS; | 643 expected_send_window += kDefaultTCPMSS; |
| 643 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 644 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 644 } | 645 } |
| 645 | 646 |
| 646 } // namespace test | 647 } // namespace test |
| 647 } // namespace net | 648 } // namespace net |
| OLD | NEW |