Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: net/quic/congestion_control/tcp_cubic_sender_packets_test.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/quic/congestion_control/tcp_cubic_sender_packets.h"
6
7 #include <algorithm>
8 #include <memory>
9
10 #include "base/logging.h"
11 #include "net/quic/congestion_control/rtt_stats.h"
12 #include "net/quic/crypto/crypto_protocol.h"
13 #include "net/quic/proto/cached_network_parameters.pb.h"
14 #include "net/quic/quic_flags.h"
15 #include "net/quic/quic_protocol.h"
16 #include "net/quic/quic_utils.h"
17 #include "net/quic/test_tools/mock_clock.h"
18 #include "net/quic/test_tools/quic_config_peer.h"
19 #include "net/quic/test_tools/quic_test_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using std::min;
23
24 namespace net {
25 namespace test {
26
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
29 // updated to be based on kInitialCongestionWindow.
30 const uint32_t kInitialCongestionWindowPackets = 10;
31 const uint32_t kMaxCongestionWindowPackets = 200;
32 const uint32_t kDefaultWindowTCP =
33 kInitialCongestionWindowPackets * kDefaultTCPMSS;
34 const float kRenoBeta = 0.7f; // Reno backoff factor.
35
36 class TcpCubicSenderPacketsPeer : public TcpCubicSenderPackets {
37 public:
38 TcpCubicSenderPacketsPeer(const QuicClock* clock,
39 bool reno,
40 QuicPacketCount max_tcp_congestion_window)
41 : TcpCubicSenderPackets(clock,
42 &rtt_stats_,
43 reno,
44 kInitialCongestionWindowPackets,
45 max_tcp_congestion_window,
46 &stats_) {}
47
48 QuicPacketCount congestion_window() { return congestion_window_; }
49
50 QuicPacketCount max_congestion_window() { return max_tcp_congestion_window_; }
51
52 QuicPacketCount slowstart_threshold() { return slowstart_threshold_; }
53
54 const HybridSlowStart& hybrid_slow_start() const {
55 return hybrid_slow_start_;
56 }
57
58 float GetRenoBeta() const { return RenoBeta(); }
59
60 RttStats rtt_stats_;
61 QuicConnectionStats stats_;
62 };
63
64 class TcpCubicSenderPacketsTest : public ::testing::Test {
65 protected:
66 TcpCubicSenderPacketsTest()
67 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
68 sender_(new TcpCubicSenderPacketsPeer(&clock_,
69 true,
70 kMaxCongestionWindowPackets)),
71 packet_number_(1),
72 acked_packet_number_(0),
73 bytes_in_flight_(0) {}
74
75 int SendAvailableSendWindow() {
76 return SendAvailableSendWindow(kDefaultTCPMSS);
77 }
78
79 int SendAvailableSendWindow(QuicPacketLength packet_length) {
80 // Send as long as TimeUntilSend returns Zero.
81 int packets_sent = 0;
82 bool can_send =
83 sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_).IsZero();
84 while (can_send) {
85 sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
86 kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
87 ++packets_sent;
88 bytes_in_flight_ += kDefaultTCPMSS;
89 can_send =
90 sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_).IsZero();
91 }
92 return packets_sent;
93 }
94
95 // Normal is that TCP acks every other segment.
96 void AckNPackets(int n) {
97 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
98 QuicTime::Delta::Zero(), clock_.Now());
99 SendAlgorithmInterface::CongestionVector acked_packets;
100 SendAlgorithmInterface::CongestionVector lost_packets;
101 for (int i = 0; i < n; ++i) {
102 ++acked_packet_number_;
103 acked_packets.push_back(
104 std::make_pair(acked_packet_number_, kDefaultTCPMSS));
105 }
106 sender_->OnCongestionEvent(true, bytes_in_flight_, acked_packets,
107 lost_packets);
108 bytes_in_flight_ -= n * kDefaultTCPMSS;
109 clock_.AdvanceTime(one_ms_);
110 }
111
112 void LoseNPackets(int n) { LoseNPackets(n, kDefaultTCPMSS); }
113
114 void LoseNPackets(int n, QuicPacketLength packet_length) {
115 SendAlgorithmInterface::CongestionVector acked_packets;
116 SendAlgorithmInterface::CongestionVector lost_packets;
117 for (int i = 0; i < n; ++i) {
118 ++acked_packet_number_;
119 lost_packets.push_back(
120 std::make_pair(acked_packet_number_, packet_length));
121 }
122 sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
123 lost_packets);
124 bytes_in_flight_ -= n * packet_length;
125 }
126
127 // Does not increment acked_packet_number_.
128 void LosePacket(QuicPacketNumber packet_number) {
129 SendAlgorithmInterface::CongestionVector acked_packets;
130 SendAlgorithmInterface::CongestionVector lost_packets;
131 lost_packets.push_back(std::make_pair(packet_number, kDefaultTCPMSS));
132 sender_->OnCongestionEvent(false, bytes_in_flight_, acked_packets,
133 lost_packets);
134 bytes_in_flight_ -= kDefaultTCPMSS;
135 }
136
137 const QuicTime::Delta one_ms_;
138 MockClock clock_;
139 std::unique_ptr<TcpCubicSenderPacketsPeer> sender_;
140 QuicPacketNumber packet_number_;
141 QuicPacketNumber acked_packet_number_;
142 QuicByteCount bytes_in_flight_;
143 };
144
145 TEST_F(TcpCubicSenderPacketsTest, SimpleSender) {
146 // At startup make sure we are at the default.
147 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
148 // At startup make sure we can send.
149 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
150 // Make sure we can send.
151 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
152 // And that window is un-affected.
153 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
154
155 // Fill the send window with data, then verify that we can't send.
156 SendAvailableSendWindow();
157 EXPECT_FALSE(
158 sender_->TimeUntilSend(clock_.Now(), sender_->GetCongestionWindow())
159 .IsZero());
160 }
161
162 TEST_F(TcpCubicSenderPacketsTest, ApplicationLimitedSlowStart) {
163 // Send exactly 10 packets and ensure the CWND ends at 14 packets.
164 const int kNumberOfAcks = 5;
165 // At startup make sure we can send.
166 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
167 // Make sure we can send.
168 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
169
170 SendAvailableSendWindow();
171 for (int i = 0; i < kNumberOfAcks; ++i) {
172 AckNPackets(2);
173 }
174 QuicByteCount bytes_to_send = sender_->GetCongestionWindow();
175 // It's expected 2 acks will arrive when the bytes_in_flight are greater than
176 // half the CWND.
177 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2, bytes_to_send);
178 }
179
180 TEST_F(TcpCubicSenderPacketsTest, ExponentialSlowStart) {
181 const int kNumberOfAcks = 20;
182 // At startup make sure we can send.
183 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
184 EXPECT_EQ(QuicBandwidth::Zero(), sender_->BandwidthEstimate());
185 // Make sure we can send.
186 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 0).IsZero());
187
188 for (int i = 0; i < kNumberOfAcks; ++i) {
189 // Send our full send window.
190 SendAvailableSendWindow();
191 AckNPackets(2);
192 }
193 const QuicByteCount cwnd = sender_->GetCongestionWindow();
194 EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks, cwnd);
195 EXPECT_EQ(QuicBandwidth::FromBytesAndTimeDelta(
196 cwnd, sender_->rtt_stats_.smoothed_rtt()),
197 sender_->BandwidthEstimate());
198 }
199
200 TEST_F(TcpCubicSenderPacketsTest, SlowStartPacketLoss) {
201 sender_->SetNumEmulatedConnections(1);
202 const int kNumberOfAcks = 10;
203 for (int i = 0; i < kNumberOfAcks; ++i) {
204 // Send our full send window.
205 SendAvailableSendWindow();
206 AckNPackets(2);
207 }
208 SendAvailableSendWindow();
209 QuicByteCount expected_send_window =
210 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
211 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
212
213 // Lose a packet to exit slow start.
214 LoseNPackets(1);
215 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
216
217 // We should now have fallen out of slow start with a reduced window.
218 expected_send_window *= kRenoBeta;
219 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
220
221 // Recovery phase. We need to ack every packet in the recovery window before
222 // we exit recovery.
223 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
224 DVLOG(1) << "number_packets: " << number_of_packets_in_window;
225 AckNPackets(packets_in_recovery_window);
226 SendAvailableSendWindow();
227 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
228
229 // We need to ack an entire window before we increase CWND by 1.
230 AckNPackets(number_of_packets_in_window - 2);
231 SendAvailableSendWindow();
232 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
233
234 // Next ack should increase cwnd by 1.
235 AckNPackets(1);
236 expected_send_window += kDefaultTCPMSS;
237 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
238
239 // Now RTO and ensure slow start gets reset.
240 EXPECT_TRUE(sender_->hybrid_slow_start().started());
241 sender_->OnRetransmissionTimeout(true);
242 EXPECT_FALSE(sender_->hybrid_slow_start().started());
243 }
244
245 TEST_F(TcpCubicSenderPacketsTest, SlowStartPacketLossWithLargeReduction) {
246 QuicConfig config;
247 QuicTagVector options;
248 options.push_back(kSSLR);
249 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
250 sender_->SetFromConfig(config, Perspective::IS_SERVER);
251
252 sender_->SetNumEmulatedConnections(1);
253 const int kNumberOfAcks = (kDefaultWindowTCP / (2 * kDefaultTCPMSS)) - 1;
254 for (int i = 0; i < kNumberOfAcks; ++i) {
255 // Send our full send window.
256 SendAvailableSendWindow();
257 AckNPackets(2);
258 }
259 SendAvailableSendWindow();
260 QuicByteCount expected_send_window =
261 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
262 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
263
264 // Lose a packet to exit slow start. We should now have fallen out of
265 // slow start with a window reduced by 1.
266 LoseNPackets(1);
267 expected_send_window -= kDefaultTCPMSS;
268 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
269
270 // Lose 5 packets in recovery and verify that congestion window is reduced
271 // further.
272 LoseNPackets(5);
273 expected_send_window -= 5 * kDefaultTCPMSS;
274 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
275 // Lose another 10 packets and ensure it reduces below half the peak CWND,
276 // because we never acked the full IW.
277 LoseNPackets(10);
278 expected_send_window -= 10 * kDefaultTCPMSS;
279 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
280
281 size_t packets_in_recovery_window = expected_send_window / kDefaultTCPMSS;
282
283 // Recovery phase. We need to ack every packet in the recovery window before
284 // we exit recovery.
285 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
286 DVLOG(1) << "number_packets: " << number_of_packets_in_window;
287 AckNPackets(packets_in_recovery_window);
288 SendAvailableSendWindow();
289 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
290
291 // We need to ack the rest of the window before cwnd increases by 1.
292 AckNPackets(number_of_packets_in_window - 1);
293 SendAvailableSendWindow();
294 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
295
296 // Next ack should increase cwnd by 1.
297 AckNPackets(1);
298 expected_send_window += kDefaultTCPMSS;
299 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
300
301 // Now RTO and ensure slow start gets reset.
302 EXPECT_TRUE(sender_->hybrid_slow_start().started());
303 sender_->OnRetransmissionTimeout(true);
304 EXPECT_FALSE(sender_->hybrid_slow_start().started());
305 }
306
307 TEST_F(TcpCubicSenderPacketsTest, SlowStartHalfPacketLossWithLargeReduction) {
308 QuicConfig config;
309 QuicTagVector options;
310 options.push_back(kSSLR);
311 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
312 sender_->SetFromConfig(config, Perspective::IS_SERVER);
313
314 sender_->SetNumEmulatedConnections(1);
315 const int kNumberOfAcks = 10;
316 for (int i = 0; i < kNumberOfAcks; ++i) {
317 // Send our full send window in half sized packets.
318 SendAvailableSendWindow(kDefaultTCPMSS / 2);
319 AckNPackets(2);
320 }
321 SendAvailableSendWindow(kDefaultTCPMSS / 2);
322 QuicByteCount expected_send_window =
323 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
324 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
325
326 // Lose a packet to exit slow start. We should now have fallen out of
327 // slow start with a window reduced by 1.
328 LoseNPackets(1);
329 expected_send_window -= kDefaultTCPMSS;
330 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
331
332 // Lose 10 packets in recovery and verify that congestion window is reduced
333 // by 5 packets.
334 LoseNPackets(10, kDefaultTCPMSS / 2);
335 expected_send_window -= 5 * kDefaultTCPMSS;
336 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
337 }
338
339 TEST_F(TcpCubicSenderPacketsTest, SlowStartPacketLossWithMaxHalfReduction) {
340 QuicConfig config;
341 QuicTagVector options;
342 options.push_back(kSSLR);
343 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
344 sender_->SetFromConfig(config, Perspective::IS_SERVER);
345
346 sender_->SetNumEmulatedConnections(1);
347 const int kNumberOfAcks = kInitialCongestionWindowPackets / 2;
348 for (int i = 0; i < kNumberOfAcks; ++i) {
349 // Send our full send window.
350 SendAvailableSendWindow();
351 AckNPackets(2);
352 }
353 SendAvailableSendWindow();
354 QuicByteCount expected_send_window =
355 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
356 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
357
358 // Lose a packet to exit slow start. We should now have fallen out of
359 // slow start with a window reduced by 1.
360 LoseNPackets(1);
361 expected_send_window -= kDefaultTCPMSS;
362 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
363
364 // Lose half the outstanding packets in recovery and verify the congestion
365 // window is only reduced by a max of half.
366 LoseNPackets(kNumberOfAcks * 2);
367 expected_send_window -= (kNumberOfAcks * 2 - 1) * kDefaultTCPMSS;
368 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
369 LoseNPackets(5);
370 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
371 }
372
373 TEST_F(TcpCubicSenderPacketsTest, NoPRRWhenLessThanOnePacketInFlight) {
374 SendAvailableSendWindow();
375 LoseNPackets(kInitialCongestionWindowPackets - 1);
376 AckNPackets(1);
377 // PRR will allow 2 packets for every ack during recovery.
378 EXPECT_EQ(2, SendAvailableSendWindow());
379 // Simulate abandoning all packets by supplying a bytes_in_flight of 0.
380 // PRR should now allow a packet to be sent, even though prr's state
381 // variables believe it has sent enough packets.
382 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->TimeUntilSend(clock_.Now(), 0));
383 }
384
385 TEST_F(TcpCubicSenderPacketsTest, SlowStartPacketLossPRR) {
386 sender_->SetNumEmulatedConnections(1);
387 // Test based on the first example in RFC6937.
388 // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
389 const int kNumberOfAcks = 5;
390 for (int i = 0; i < kNumberOfAcks; ++i) {
391 // Send our full send window.
392 SendAvailableSendWindow();
393 AckNPackets(2);
394 }
395 SendAvailableSendWindow();
396 QuicByteCount expected_send_window =
397 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
398 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
399
400 LoseNPackets(1);
401
402 // We should now have fallen out of slow start with a reduced window.
403 size_t send_window_before_loss = expected_send_window;
404 expected_send_window *= kRenoBeta;
405 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
406
407 // Testing TCP proportional rate reduction.
408 // We should send packets paced over the received acks for the remaining
409 // outstanding packets. The number of packets before we exit recovery is the
410 // original CWND minus the packet that has been lost and the one which
411 // triggered the loss.
412 size_t remaining_packets_in_recovery =
413 send_window_before_loss / kDefaultTCPMSS - 2;
414
415 for (size_t i = 0; i < remaining_packets_in_recovery; ++i) {
416 AckNPackets(1);
417 SendAvailableSendWindow();
418 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
419 }
420
421 // We need to ack another window before we increase CWND by 1.
422 size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
423 for (size_t i = 0; i < number_of_packets_in_window; ++i) {
424 AckNPackets(1);
425 EXPECT_EQ(1, SendAvailableSendWindow());
426 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
427 }
428
429 AckNPackets(1);
430 expected_send_window += kDefaultTCPMSS;
431 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
432 }
433
434 TEST_F(TcpCubicSenderPacketsTest, SlowStartBurstPacketLossPRR) {
435 sender_->SetNumEmulatedConnections(1);
436 // Test based on the second example in RFC6937, though we also implement
437 // forward acknowledgements, so the first two incoming acks will trigger
438 // PRR immediately.
439 // Ack 20 packets in 10 acks to raise the CWND to 30.
440 const int kNumberOfAcks = 10;
441 for (int i = 0; i < kNumberOfAcks; ++i) {
442 // Send our full send window.
443 SendAvailableSendWindow();
444 AckNPackets(2);
445 }
446 SendAvailableSendWindow();
447 QuicByteCount expected_send_window =
448 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
449 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
450
451 // Lose one more than the congestion window reduction, so that after loss,
452 // bytes_in_flight is lesser than the congestion window.
453 size_t send_window_after_loss = kRenoBeta * expected_send_window;
454 size_t num_packets_to_lose =
455 (expected_send_window - send_window_after_loss) / kDefaultTCPMSS + 1;
456 LoseNPackets(num_packets_to_lose);
457 // Immediately after the loss, ensure at least one packet can be sent.
458 // Losses without subsequent acks can occur with timer based loss detection.
459 EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), bytes_in_flight_).IsZero());
460 AckNPackets(1);
461
462 // We should now have fallen out of slow start with a reduced window.
463 expected_send_window *= kRenoBeta;
464 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
465
466 // Only 2 packets should be allowed to be sent, per PRR-SSRB
467 EXPECT_EQ(2, SendAvailableSendWindow());
468
469 // Ack the next packet, which triggers another loss.
470 LoseNPackets(1);
471 AckNPackets(1);
472
473 // Send 2 packets to simulate PRR-SSRB.
474 EXPECT_EQ(2, SendAvailableSendWindow());
475
476 // Ack the next packet, which triggers another loss.
477 LoseNPackets(1);
478 AckNPackets(1);
479
480 // Send 2 packets to simulate PRR-SSRB.
481 EXPECT_EQ(2, SendAvailableSendWindow());
482
483 // Exit recovery and return to sending at the new rate.
484 for (int i = 0; i < kNumberOfAcks; ++i) {
485 AckNPackets(1);
486 EXPECT_EQ(1, SendAvailableSendWindow());
487 }
488 }
489
490 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindow) {
491 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
492 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold());
493
494 // Expect the window to decrease to the minimum once the RTO fires
495 // and slow start threshold to be set to 1/2 of the CWND.
496 sender_->OnRetransmissionTimeout(true);
497 EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
498 EXPECT_EQ(5u, sender_->slowstart_threshold());
499 }
500
501 TEST_F(TcpCubicSenderPacketsTest, RTOCongestionWindowNoRetransmission) {
502 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
503
504 // Expect the window to remain unchanged if the RTO fires but no
505 // packets are retransmitted.
506 sender_->OnRetransmissionTimeout(false);
507 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
508 }
509
510 TEST_F(TcpCubicSenderPacketsTest, RetransmissionDelay) {
511 const int64_t kRttMs = 10;
512 const int64_t kDeviationMs = 3;
513 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
514
515 sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
516 QuicTime::Delta::Zero(), clock_.Now());
517
518 // Initial value is to set the median deviation to half of the initial
519 // rtt, the median in then multiplied by a factor of 4 and finally the
520 // smoothed rtt is added which is the initial rtt.
521 QuicTime::Delta expected_delay =
522 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
523 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
524
525 for (int i = 0; i < 100; ++i) {
526 // Run to make sure that we converge.
527 sender_->rtt_stats_.UpdateRtt(
528 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
529 QuicTime::Delta::Zero(), clock_.Now());
530 sender_->rtt_stats_.UpdateRtt(
531 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
532 QuicTime::Delta::Zero(), clock_.Now());
533 }
534 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
535
536 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.smoothed_rtt().ToMilliseconds(), 1);
537 EXPECT_NEAR(expected_delay.ToMilliseconds(),
538 sender_->RetransmissionDelay().ToMilliseconds(), 1);
539 EXPECT_EQ(static_cast<int64_t>(
540 sender_->GetCongestionWindow() * kNumMicrosPerSecond /
541 sender_->rtt_stats_.smoothed_rtt().ToMicroseconds()),
542 sender_->BandwidthEstimate().ToBytesPerSecond());
543 }
544
545 TEST_F(TcpCubicSenderPacketsTest, SlowStartMaxSendWindow) {
546 const QuicPacketCount kMaxCongestionWindowTCP = 50;
547 const int kNumberOfAcks = 100;
548 sender_.reset(
549 new TcpCubicSenderPacketsPeer(&clock_, false, kMaxCongestionWindowTCP));
550
551 for (int i = 0; i < kNumberOfAcks; ++i) {
552 // Send our full send window.
553 SendAvailableSendWindow();
554 AckNPackets(2);
555 }
556 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
557 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
558 }
559
560 TEST_F(TcpCubicSenderPacketsTest, TcpRenoMaxCongestionWindow) {
561 const QuicPacketCount kMaxCongestionWindowTCP = 50;
562 const int kNumberOfAcks = 1000;
563 sender_.reset(
564 new TcpCubicSenderPacketsPeer(&clock_, true, kMaxCongestionWindowTCP));
565
566 SendAvailableSendWindow();
567 AckNPackets(2);
568 // Make sure we fall out of slow start.
569 LoseNPackets(1);
570
571 for (int i = 0; i < kNumberOfAcks; ++i) {
572 // Send our full send window.
573 SendAvailableSendWindow();
574 AckNPackets(2);
575 }
576
577 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
578 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
579 }
580
581 TEST_F(TcpCubicSenderPacketsTest, TcpCubicMaxCongestionWindow) {
582 const QuicPacketCount kMaxCongestionWindowTCP = 50;
583 // Set to 10000 to compensate for small cubic alpha.
584 const int kNumberOfAcks = 10000;
585
586 sender_.reset(
587 new TcpCubicSenderPacketsPeer(&clock_, false, kMaxCongestionWindowTCP));
588
589 SendAvailableSendWindow();
590 AckNPackets(2);
591 // Make sure we fall out of slow start.
592 LoseNPackets(1);
593
594 for (int i = 0; i < kNumberOfAcks; ++i) {
595 // Send our full send window.
596 SendAvailableSendWindow();
597 AckNPackets(2);
598 }
599
600 QuicByteCount expected_send_window = kMaxCongestionWindowTCP * kDefaultTCPMSS;
601 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
602 }
603
604 TEST_F(TcpCubicSenderPacketsTest, TcpCubicResetEpochOnQuiescence) {
605 const int kMaxCongestionWindow = 50;
606 const QuicByteCount kMaxCongestionWindowBytes =
607 kMaxCongestionWindow * kDefaultTCPMSS;
608 sender_.reset(
609 new TcpCubicSenderPacketsPeer(&clock_, false, kMaxCongestionWindow));
610
611 int num_sent = SendAvailableSendWindow();
612
613 // Make sure we fall out of slow start.
614 QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
615 LoseNPackets(1);
616 EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
617
618 // Ack the rest of the outstanding packets to get out of recovery.
619 for (int i = 1; i < num_sent; ++i) {
620 AckNPackets(1);
621 }
622 EXPECT_EQ(0u, bytes_in_flight_);
623
624 // Send a new window of data and ack all; cubic growth should occur.
625 saved_cwnd = sender_->GetCongestionWindow();
626 num_sent = SendAvailableSendWindow();
627 for (int i = 0; i < num_sent; ++i) {
628 AckNPackets(1);
629 }
630 EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
631 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
632 EXPECT_EQ(0u, bytes_in_flight_);
633
634 // Quiescent time of 100 seconds
635 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100000));
636
637 // Send new window of data and ack one packet. Cubic epoch should have
638 // been reset; ensure cwnd increase is not dramatic.
639 saved_cwnd = sender_->GetCongestionWindow();
640 SendAvailableSendWindow();
641 AckNPackets(1);
642 EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
643 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
644 }
645
646 TEST_F(TcpCubicSenderPacketsTest, TcpCubicShiftedEpochOnQuiescence) {
647 ValueRestore<bool> old_flag(&FLAGS_shift_quic_cubic_epoch_when_app_limited,
648 true);
649 const int kMaxCongestionWindow = 50;
650 const QuicByteCount kMaxCongestionWindowBytes =
651 kMaxCongestionWindow * kDefaultTCPMSS;
652 sender_.reset(
653 new TcpCubicSenderPacketsPeer(&clock_, false, kMaxCongestionWindow));
654
655 int num_sent = SendAvailableSendWindow();
656
657 // Make sure we fall out of slow start.
658 QuicByteCount saved_cwnd = sender_->GetCongestionWindow();
659 LoseNPackets(1);
660 EXPECT_GT(saved_cwnd, sender_->GetCongestionWindow());
661
662 // Ack the rest of the outstanding packets to get out of recovery.
663 for (int i = 1; i < num_sent; ++i) {
664 AckNPackets(1);
665 }
666 EXPECT_EQ(0u, bytes_in_flight_);
667
668 // Send a new window of data and ack all; cubic growth should occur.
669 saved_cwnd = sender_->GetCongestionWindow();
670 num_sent = SendAvailableSendWindow();
671 for (int i = 0; i < num_sent; ++i) {
672 AckNPackets(1);
673 }
674 EXPECT_LT(saved_cwnd, sender_->GetCongestionWindow());
675 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
676 EXPECT_EQ(0u, bytes_in_flight_);
677
678 // Quiescent time of 100 seconds
679 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(100));
680
681 // Send new window of data and ack one packet. Cubic epoch should have
682 // been reset; ensure cwnd increase is not dramatic.
683 saved_cwnd = sender_->GetCongestionWindow();
684 SendAvailableSendWindow();
685 AckNPackets(1);
686 EXPECT_NEAR(saved_cwnd, sender_->GetCongestionWindow(), kDefaultTCPMSS);
687 EXPECT_GT(kMaxCongestionWindowBytes, sender_->GetCongestionWindow());
688 }
689
690 TEST_F(TcpCubicSenderPacketsTest, MultipleLossesInOneWindow) {
691 SendAvailableSendWindow();
692 const QuicByteCount initial_window = sender_->GetCongestionWindow();
693 LosePacket(acked_packet_number_ + 1);
694 const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
695 EXPECT_GT(initial_window, post_loss_window);
696 LosePacket(acked_packet_number_ + 3);
697 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
698 LosePacket(packet_number_ - 1);
699 EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
700
701 // Lose a later packet and ensure the window decreases.
702 LosePacket(packet_number_);
703 EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
704 }
705
706 TEST_F(TcpCubicSenderPacketsTest, DontTrackAckPackets) {
707 // Send a packet with no retransmittable data, and ensure it's not tracked.
708 EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
709 packet_number_++, kDefaultTCPMSS,
710 NO_RETRANSMITTABLE_DATA));
711
712 // Send a data packet with retransmittable data, and ensure it is tracked.
713 EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
714 packet_number_++, kDefaultTCPMSS,
715 HAS_RETRANSMITTABLE_DATA));
716 }
717
718 TEST_F(TcpCubicSenderPacketsTest, ConfigureInitialWindow) {
719 QuicConfig config;
720
721 QuicTagVector options;
722 options.push_back(kIW03);
723 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
724 sender_->SetFromConfig(config, Perspective::IS_SERVER);
725 EXPECT_EQ(3u, sender_->congestion_window());
726
727 options.clear();
728 options.push_back(kIW10);
729 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
730 sender_->SetFromConfig(config, Perspective::IS_SERVER);
731 EXPECT_EQ(10u, sender_->congestion_window());
732
733 options.clear();
734 options.push_back(kIW20);
735 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
736 sender_->SetFromConfig(config, Perspective::IS_SERVER);
737 EXPECT_EQ(20u, sender_->congestion_window());
738
739 options.clear();
740 options.push_back(kIW50);
741 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
742 sender_->SetFromConfig(config, Perspective::IS_SERVER);
743 EXPECT_EQ(50u, sender_->congestion_window());
744 }
745
746 TEST_F(TcpCubicSenderPacketsTest, ConfigureMinimumWindow) {
747 QuicConfig config;
748
749 // Verify that kCOPT: kMIN1 forces the min CWND to 1 packet.
750 QuicTagVector options;
751 options.push_back(kMIN1);
752 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
753 sender_->SetFromConfig(config, Perspective::IS_SERVER);
754 sender_->OnRetransmissionTimeout(true);
755 EXPECT_EQ(1u, sender_->congestion_window());
756 }
757
758 TEST_F(TcpCubicSenderPacketsTest,
759 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
760 sender_->SetNumEmulatedConnections(2);
761 // Ack 10 packets in 5 acks to raise the CWND to 20.
762 const int kNumberOfAcks = 5;
763 for (int i = 0; i < kNumberOfAcks; ++i) {
764 // Send our full send window.
765 SendAvailableSendWindow();
766 AckNPackets(2);
767 }
768 SendAvailableSendWindow();
769 QuicByteCount expected_send_window =
770 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
771 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
772
773 LoseNPackets(1);
774
775 // We should now have fallen out of slow start with a reduced window.
776 expected_send_window = expected_send_window * sender_->GetRenoBeta();
777 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
778
779 // No congestion window growth should occur in recovery phase, i.e., until the
780 // currently outstanding 20 packets are acked.
781 for (int i = 0; i < 10; ++i) {
782 // Send our full send window.
783 SendAvailableSendWindow();
784 EXPECT_TRUE(sender_->InRecovery());
785 AckNPackets(2);
786 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
787 }
788 EXPECT_FALSE(sender_->InRecovery());
789
790 // Out of recovery now. Congestion window should not grow for half an RTT.
791 size_t packets_in_send_window = expected_send_window / kDefaultTCPMSS;
792 SendAvailableSendWindow();
793 AckNPackets(packets_in_send_window / 2 - 2);
794 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
795
796 // Next ack should increase congestion window by 1MSS.
797 SendAvailableSendWindow();
798 AckNPackets(2);
799 expected_send_window += kDefaultTCPMSS;
800 packets_in_send_window += 1;
801 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
802
803 // Congestion window should remain steady again for half an RTT.
804 SendAvailableSendWindow();
805 AckNPackets(packets_in_send_window / 2 - 1);
806 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
807
808 // Next ack should cause congestion window to grow by 1MSS.
809 SendAvailableSendWindow();
810 AckNPackets(2);
811 expected_send_window += kDefaultTCPMSS;
812 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
813 }
814
815 TEST_F(TcpCubicSenderPacketsTest,
816 1ConnectionCongestionAvoidanceAtEndOfRecovery) {
817 sender_->SetNumEmulatedConnections(1);
818 // Ack 10 packets in 5 acks to raise the CWND to 20.
819 const int kNumberOfAcks = 5;
820 for (int i = 0; i < kNumberOfAcks; ++i) {
821 // Send our full send window.
822 SendAvailableSendWindow();
823 AckNPackets(2);
824 }
825 SendAvailableSendWindow();
826 QuicByteCount expected_send_window =
827 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
828 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
829
830 LoseNPackets(1);
831
832 // We should now have fallen out of slow start with a reduced window.
833 expected_send_window *= kRenoBeta;
834 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
835
836 // No congestion window growth should occur in recovery phase, i.e., until the
837 // currently outstanding 20 packets are acked.
838 for (int i = 0; i < 10; ++i) {
839 // Send our full send window.
840 SendAvailableSendWindow();
841 EXPECT_TRUE(sender_->InRecovery());
842 AckNPackets(2);
843 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
844 }
845 EXPECT_FALSE(sender_->InRecovery());
846
847 // Out of recovery now. Congestion window should not grow during RTT.
848 for (uint64_t i = 0; i < expected_send_window / kDefaultTCPMSS - 2; i += 2) {
849 // Send our full send window.
850 SendAvailableSendWindow();
851 AckNPackets(2);
852 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
853 }
854
855 // Next ack should cause congestion window to grow by 1MSS.
856 SendAvailableSendWindow();
857 AckNPackets(2);
858 expected_send_window += kDefaultTCPMSS;
859 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
860 }
861
862 TEST_F(TcpCubicSenderPacketsTest, BandwidthResumption) {
863 // Test that when provided with CachedNetworkParameters and opted in to the
864 // bandwidth resumption experiment, that the TcpCubicSenderPackets sets
865 // initial CWND appropriately.
866
867 // Set some common values.
868 CachedNetworkParameters cached_network_params;
869 const QuicPacketCount kNumberOfPackets = 123;
870 const int kBandwidthEstimateBytesPerSecond =
871 kNumberOfPackets * kDefaultTCPMSS;
872 cached_network_params.set_bandwidth_estimate_bytes_per_second(
873 kBandwidthEstimateBytesPerSecond);
874 cached_network_params.set_min_rtt_ms(1000);
875
876 // Make sure that a bandwidth estimate results in a changed CWND.
877 cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
878 (kNumSecondsPerHour - 1));
879 sender_->ResumeConnectionState(cached_network_params, false);
880 EXPECT_EQ(kNumberOfPackets, sender_->congestion_window());
881
882 // Resumed CWND is limited to be in a sensible range.
883 cached_network_params.set_bandwidth_estimate_bytes_per_second(
884 (kMaxCongestionWindowPackets + 1) * kDefaultTCPMSS);
885 sender_->ResumeConnectionState(cached_network_params, false);
886 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->congestion_window());
887
888 if (FLAGS_quic_no_lower_bw_resumption_limit) {
889 // Resume with an illegal value of 0 and verify the server uses 1 instead.
890 cached_network_params.set_bandwidth_estimate_bytes_per_second(0);
891 sender_->ResumeConnectionState(cached_network_params, false);
892 EXPECT_EQ(sender_->min_congestion_window(), sender_->congestion_window());
893 } else {
894 cached_network_params.set_bandwidth_estimate_bytes_per_second(
895 (kMinCongestionWindowForBandwidthResumption - 1) * kDefaultTCPMSS);
896 sender_->ResumeConnectionState(cached_network_params, false);
897 EXPECT_EQ(kMinCongestionWindowForBandwidthResumption,
898 sender_->congestion_window());
899 }
900
901 // Resume to the max value.
902 cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
903 kMaxCongestionWindowPackets * kDefaultTCPMSS);
904 sender_->ResumeConnectionState(cached_network_params, true);
905 EXPECT_EQ(kMaxCongestionWindowPackets * kDefaultTCPMSS,
906 sender_->GetCongestionWindow());
907 }
908
909 TEST_F(TcpCubicSenderPacketsTest, PaceBelowCWND) {
910 QuicConfig config;
911
912 // Verify that kCOPT: kMIN4 forces the min CWND to 1 packet, but allows up
913 // to 4 to be sent.
914 QuicTagVector options;
915 options.push_back(kMIN4);
916 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
917 sender_->SetFromConfig(config, Perspective::IS_SERVER);
918 sender_->OnRetransmissionTimeout(true);
919 EXPECT_EQ(1u, sender_->congestion_window());
920 EXPECT_TRUE(
921 sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero());
922 EXPECT_TRUE(
923 sender_->TimeUntilSend(QuicTime::Zero(), 2 * kDefaultTCPMSS).IsZero());
924 EXPECT_TRUE(
925 sender_->TimeUntilSend(QuicTime::Zero(), 3 * kDefaultTCPMSS).IsZero());
926 EXPECT_FALSE(
927 sender_->TimeUntilSend(QuicTime::Zero(), 4 * kDefaultTCPMSS).IsZero());
928 }
929
930 TEST_F(TcpCubicSenderPacketsTest, NoPRR) {
931 QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(100);
932 sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), QuicTime::Zero());
933
934 sender_->SetNumEmulatedConnections(1);
935 // Verify that kCOPT: kNPRR allows all packets to be sent, even if only one
936 // ack has been received.
937 QuicTagVector options;
938 options.push_back(kNPRR);
939 QuicConfig config;
940 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
941 sender_->SetFromConfig(config, Perspective::IS_SERVER);
942 SendAvailableSendWindow();
943 LoseNPackets(9);
944 AckNPackets(1);
945
946 // We should now have fallen out of slow start with a reduced window.
947 EXPECT_EQ(kRenoBeta * kDefaultWindowTCP, sender_->GetCongestionWindow());
948 const QuicPacketCount window_in_packets =
949 kRenoBeta * kDefaultWindowTCP / kDefaultTCPMSS;
950 const QuicBandwidth expected_pacing_rate =
951 QuicBandwidth::FromBytesAndTimeDelta(kRenoBeta * kDefaultWindowTCP,
952 sender_->rtt_stats_.smoothed_rtt());
953 EXPECT_EQ(expected_pacing_rate, sender_->PacingRate(0));
954 EXPECT_EQ(window_in_packets,
955 static_cast<uint64_t>(SendAvailableSendWindow()));
956 EXPECT_EQ(expected_pacing_rate,
957 sender_->PacingRate(kRenoBeta * kDefaultWindowTCP));
958 }
959
960 TEST_F(TcpCubicSenderPacketsTest, PaceSlowerAboveCwnd) {
961 ValueRestore<bool> old_flag(&FLAGS_quic_rate_based_sending, true);
962 QuicTime::Delta rtt(QuicTime::Delta::FromMilliseconds(60));
963 sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now());
964
965 QuicConfig config;
966 QuicTagVector options;
967 options.push_back(kRATE);
968 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
969 sender_->SetFromConfig(config, Perspective::IS_SERVER);
970 EXPECT_EQ(10u, sender_->congestion_window());
971 sender_->SetNumEmulatedConnections(1);
972 // Lose a packet to exit slow start.
973 LoseNPackets(1);
974 const QuicPacketCount cwnd = 7;
975 EXPECT_EQ(cwnd * kDefaultTCPMSS, sender_->GetCongestionWindow());
976
977 EXPECT_TRUE(
978 sender_->TimeUntilSend(QuicTime::Zero(), kDefaultTCPMSS).IsZero());
979 EXPECT_EQ(
980 sender_->PacingRate(kDefaultTCPMSS),
981 QuicBandwidth::FromBytesAndTimeDelta(7 * kDefaultTCPMSS, rtt) * 1.25);
982 for (QuicPacketCount i = cwnd + 1; i < 1.5 * cwnd; ++i) {
983 EXPECT_TRUE(
984 sender_->TimeUntilSend(QuicTime::Zero(), i * kDefaultTCPMSS).IsZero());
985 EXPECT_EQ(sender_->PacingRate(i * kDefaultTCPMSS),
986 QuicBandwidth::FromBytesAndTimeDelta(cwnd * kDefaultTCPMSS, rtt) *
987 0.75);
988 }
989 EXPECT_FALSE(
990 sender_->TimeUntilSend(QuicTime::Zero(), 11 * kDefaultTCPMSS).IsZero());
991 }
992
993 TEST_F(TcpCubicSenderPacketsTest, ResetAfterConnectionMigration) {
994 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
995 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold());
996
997 // Starts with slow start.
998 sender_->SetNumEmulatedConnections(1);
999 const int kNumberOfAcks = 10;
1000 for (int i = 0; i < kNumberOfAcks; ++i) {
1001 // Send our full send window.
1002 SendAvailableSendWindow();
1003 AckNPackets(2);
1004 }
1005 SendAvailableSendWindow();
1006 QuicByteCount expected_send_window =
1007 kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
1008 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
1009
1010 // Loses a packet to exit slow start.
1011 LoseNPackets(1);
1012
1013 // We should now have fallen out of slow start with a reduced window. Slow
1014 // start threshold is also updated.
1015 expected_send_window *= kRenoBeta;
1016 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
1017 EXPECT_EQ(expected_send_window / kDefaultTCPMSS,
1018 sender_->slowstart_threshold());
1019
1020 // Resets cwnd and slow start threshold on connection migrations.
1021 sender_->OnConnectionMigration();
1022 EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
1023 EXPECT_EQ(kMaxCongestionWindowPackets, sender_->slowstart_threshold());
1024 EXPECT_FALSE(sender_->hybrid_slow_start().started());
1025 }
1026
1027 TEST_F(TcpCubicSenderPacketsTest, DefaultMaxCwnd) {
1028 RttStats rtt_stats;
1029 QuicConnectionStats stats;
1030 std::unique_ptr<SendAlgorithmInterface> sender(SendAlgorithmInterface::Create(
1031 &clock_, &rtt_stats, kCubic, &stats, kInitialCongestionWindow));
1032
1033 SendAlgorithmInterface::CongestionVector acked_packets;
1034 SendAlgorithmInterface::CongestionVector missing_packets;
1035 for (uint64_t i = 1; i < kDefaultMaxCongestionWindowPackets; ++i) {
1036 acked_packets.clear();
1037 acked_packets.push_back(std::make_pair(i, 1350));
1038 sender->OnCongestionEvent(true, sender->GetCongestionWindow(),
1039 acked_packets, missing_packets);
1040 }
1041 EXPECT_EQ(kDefaultMaxCongestionWindowPackets,
1042 sender->GetCongestionWindow() / kDefaultTCPMSS);
1043 }
1044
1045 } // namespace test
1046 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/tcp_cubic_sender_packets.cc ('k') | net/quic/congestion_control/windowed_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698