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 |