Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / quic / congestion_control / tcp_cubic_sender_test.cc
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 <algorithm>
6
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/quic/congestion_control/tcp_cubic_sender.h"
10 #include "net/quic/congestion_control/tcp_receiver.h"
11 #include "net/quic/test_tools/mock_clock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using std::min;
15
16 namespace net {
17 namespace test {
18
19 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS;
20
21 // TODO(ianswett): Remove 10000 once b/10075719 is fixed.
22 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000;
23
24 class TcpCubicSenderPeer : public TcpCubicSender {
25  public:
26   TcpCubicSenderPeer(const QuicClock* clock,
27                      bool reno,
28                      QuicTcpCongestionWindow max_tcp_congestion_window)
29       : TcpCubicSender(clock, reno, max_tcp_congestion_window) {
30   }
31
32   QuicTcpCongestionWindow congestion_window() {
33     return congestion_window_;
34   }
35
36   using TcpCubicSender::AvailableSendWindow;
37   using TcpCubicSender::SendWindow;
38 };
39
40 class TcpCubicSenderTest : public ::testing::Test {
41  protected:
42   TcpCubicSenderTest()
43       : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
44         sender_(new TcpCubicSenderPeer(&clock_, true,
45                                        kDefaultMaxCongestionWindowTCP)),
46         receiver_(new TcpReceiver()),
47         sequence_number_(1),
48         acked_sequence_number_(0) {
49   }
50
51   int SendAvailableSendWindow() {
52     // Send as long as TimeUntilSend returns Zero.
53     int packets_sent = 0;
54     bool can_send = sender_->TimeUntilSend(
55         clock_.Now(), NOT_RETRANSMISSION,
56         HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero();
57     while (can_send) {
58       sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS,
59                             NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
60       ++packets_sent;
61       can_send = sender_->TimeUntilSend(
62           clock_.Now(), NOT_RETRANSMISSION,
63           HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero();
64     }
65     return packets_sent;
66   }
67
68   // Normal is that TCP acks every other segment.
69   void AckNPackets(int n) {
70     for (int i = 0; i < n; ++i) {
71       ++acked_sequence_number_;
72       sender_->UpdateRtt(QuicTime::Delta::FromMilliseconds(60));
73       sender_->OnPacketAcked(acked_sequence_number_, kDefaultTCPMSS);
74     }
75     clock_.AdvanceTime(one_ms_);  // 1 millisecond.
76   }
77
78   void LoseNPackets(int n) {
79     for (int i = 0; i < n; ++i) {
80       ++acked_sequence_number_;
81       sender_->OnPacketAbandoned(acked_sequence_number_, kDefaultTCPMSS);
82       sender_->OnPacketLost(acked_sequence_number_, clock_.Now());
83     }
84   }
85
86   const QuicTime::Delta one_ms_;
87   MockClock clock_;
88   SendAlgorithmInterface::SentPacketsMap not_used_;
89   scoped_ptr<TcpCubicSenderPeer> sender_;
90   scoped_ptr<TcpReceiver> receiver_;
91   QuicPacketSequenceNumber sequence_number_;
92   QuicPacketSequenceNumber acked_sequence_number_;
93 };
94
95 TEST_F(TcpCubicSenderTest, SimpleSender) {
96   QuicCongestionFeedbackFrame feedback;
97   // At startup make sure we are at the default.
98   EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow());
99   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
100   // At startup make sure we can send.
101   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
102       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
103   // Get default QuicCongestionFeedbackFrame from receiver.
104   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
105   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
106                                                  not_used_);
107   // Make sure we can send.
108   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
109       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
110   // And that window is un-affected.
111   EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow());
112   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
113
114   // A retransmit should always return 0.
115   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
116       NACK_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
117 }
118
119 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
120   const int kNumberOfAcks = 20;
121   QuicCongestionFeedbackFrame feedback;
122   // At startup make sure we can send.
123   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
124       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
125   // Get default QuicCongestionFeedbackFrame from receiver.
126   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
127   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
128                                                  not_used_);
129   // Make sure we can send.
130   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
131       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
132
133   for (int i = 0; i < kNumberOfAcks; ++i) {
134     // Send our full send window.
135     SendAvailableSendWindow();
136     AckNPackets(2);
137   }
138   QuicByteCount bytes_to_send = sender_->SendWindow();
139   EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks,
140             bytes_to_send);
141 }
142
143 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) {
144   // Make sure that we fall out of slow start when we send ACK train longer
145   // than half the RTT, in this test case 30ms, which is more than 30 calls to
146   // Ack2Packets in one round.
147   // Since we start at 10 packet first round will be 5 second round 10 etc
148   // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30
149   const int kNumberOfAcks = 65;
150   QuicCongestionFeedbackFrame feedback;
151   // At startup make sure we can send.
152   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
153       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
154   // Get default QuicCongestionFeedbackFrame from receiver.
155   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
156   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
157                                                  not_used_);
158   // Make sure we can send.
159   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
160       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
161
162   for (int i = 0; i < kNumberOfAcks; ++i) {
163     // Send our full send window.
164     SendAvailableSendWindow();
165     AckNPackets(2);
166   }
167   QuicByteCount expected_send_window =
168       kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
169   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
170   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
171
172   // We should now have fallen out of slow start.
173   // Testing Reno phase.
174   // We should need 141(65*2+1+10) ACK:ed packets before increasing window by
175   // one.
176   for (int i = 0; i < 70; ++i) {
177     SendAvailableSendWindow();
178     AckNPackets(2);
179     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
180   }
181   SendAvailableSendWindow();
182   AckNPackets(2);
183   expected_send_window += kDefaultTCPMSS;
184   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
185 }
186
187 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
188   // Make sure that we fall out of slow start when we encounter a packet loss.
189   QuicCongestionFeedbackFrame feedback;
190   // At startup make sure we can send.
191   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
192       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
193   // Get default QuicCongestionFeedbackFrame from receiver.
194   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
195   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
196                                                  not_used_);
197   // Make sure we can send.
198   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
199       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
200
201   const int kNumberOfAcks = 10;
202   for (int i = 0; i < kNumberOfAcks; ++i) {
203     // Send our full send window.
204     SendAvailableSendWindow();
205     AckNPackets(2);
206   }
207   SendAvailableSendWindow();
208   QuicByteCount expected_send_window = kDefaultWindowTCP +
209       (kDefaultTCPMSS * 2 * kNumberOfAcks);
210   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
211
212   sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
213   ++acked_sequence_number_;
214
215   // Make sure that we can send right now due to limited transmit.
216   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION,
217       HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
218
219   // We should now have fallen out of slow start.
220   // We expect window to be cut in half by Reno.
221   expected_send_window /= 2;
222   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
223
224   // Testing Reno phase.
225   // We need to ack half of the pending packet before we can send again.
226   size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
227   AckNPackets(number_of_packets_in_window);
228   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
229   EXPECT_EQ(0u, sender_->AvailableSendWindow());
230
231   // We need to ack every packet in the window before we exit recovery.
232   for (size_t i = 0; i < number_of_packets_in_window; ++i) {
233     AckNPackets(1);
234     SendAvailableSendWindow();
235     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
236   }
237
238   // We need to ack another window before we increase CWND by 1.
239   for (size_t i = 0; i < number_of_packets_in_window - 1; ++i) {
240     AckNPackets(1);
241     SendAvailableSendWindow();
242     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
243   }
244
245   AckNPackets(1);
246   expected_send_window += kDefaultTCPMSS;
247   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
248 }
249
250 TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
251   // Test based on the first example in RFC6937.
252   // Make sure that we fall out of slow start when we encounter a packet loss.
253   QuicCongestionFeedbackFrame feedback;
254   // At startup make sure we can send.
255   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
256       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
257   // Get default QuicCongestionFeedbackFrame from receiver.
258   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
259   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
260                                                  not_used_);
261
262   // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
263   const int kNumberOfAcks = 5;
264   for (int i = 0; i < kNumberOfAcks; ++i) {
265     // Send our full send window.
266     SendAvailableSendWindow();
267     AckNPackets(2);
268   }
269   SendAvailableSendWindow();
270   QuicByteCount expected_send_window = kDefaultWindowTCP +
271       (kDefaultTCPMSS * 2 * kNumberOfAcks);
272   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
273
274   LoseNPackets(1);
275
276   // We should now have fallen out of slow start.
277   // We expect window to be cut in half by Reno.
278   expected_send_window /= 2;
279   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
280
281   // Send 1 packet to simulate limited transmit.
282   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION,
283       HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
284   EXPECT_EQ(1, SendAvailableSendWindow());
285
286   // Testing TCP proportional rate reduction.
287   // We should send one packet for every two received acks over the remaining
288   // 18 outstanding packets.
289   size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
290   // The number of packets before we exit recovery is the original CWND minus
291   // the packet that has been lost and the one which triggered the loss.
292   size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1;
293   for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) {
294     AckNPackets(2);
295     EXPECT_TRUE(sender_->TimeUntilSend(
296         clock_.Now(), NOT_RETRANSMISSION,
297         HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
298     EXPECT_EQ(0u, sender_->AvailableSendWindow());
299     EXPECT_EQ(1, SendAvailableSendWindow());
300     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
301   }
302   // If there is one more packet to ack before completing recovery, ack it.
303   if (remaining_packets_in_recovery % 2 == 1) {
304     AckNPackets(1);
305   }
306
307   // We need to ack another window before we increase CWND by 1.
308   for (size_t i = 0; i < number_of_packets_in_window; ++i) {
309     AckNPackets(1);
310     EXPECT_EQ(1, SendAvailableSendWindow());
311     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
312   }
313
314   AckNPackets(1);
315   expected_send_window += kDefaultTCPMSS;
316   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
317 }
318
319 TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
320   // Test based on the second example in RFC6937, though we also implement
321   // forward acknowledgements, so the first two incoming acks will trigger
322   // PRR immediately.
323   // Make sure that we fall out of slow start when we encounter a packet loss.
324   QuicCongestionFeedbackFrame feedback;
325   // At startup make sure we can send.
326   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
327       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
328   // Get default QuicCongestionFeedbackFrame from receiver.
329   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
330   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
331                                                  not_used_);
332
333   // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
334   const int kNumberOfAcks = 5;
335   for (int i = 0; i < kNumberOfAcks; ++i) {
336     // Send our full send window.
337     SendAvailableSendWindow();
338     AckNPackets(2);
339   }
340   SendAvailableSendWindow();
341   QuicByteCount expected_send_window = kDefaultWindowTCP +
342       (kDefaultTCPMSS * 2 * kNumberOfAcks);
343   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
344
345   // Ack a packet with a 15 packet gap, losing 13 of them due to FACK.
346   sender_->OnPacketAcked(acked_sequence_number_ + 15, kDefaultTCPMSS);
347   LoseNPackets(13);
348
349   // We should now have fallen out of slow start.
350   // We expect window to be cut in half by Reno.
351   expected_send_window /= 2;
352   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
353
354   // Only 2 packets should be allowed to be sent, per PRR-SSRB
355   EXPECT_EQ(2, SendAvailableSendWindow());
356
357   // Ack the next packet, which triggers another loss.
358   sender_->OnPacketAcked(acked_sequence_number_ + 4, kDefaultTCPMSS);
359   LoseNPackets(1);
360
361   // Send 2 packets to simulate PRR-SSRB.
362   EXPECT_EQ(2, SendAvailableSendWindow());
363
364   // Ack the next packet, which triggers another loss.
365   sender_->OnPacketAcked(acked_sequence_number_ + 4, kDefaultTCPMSS);
366   LoseNPackets(1);
367
368   // Send 2 packets to simulate PRR-SSRB.
369   EXPECT_EQ(2, SendAvailableSendWindow());
370
371   AckNPackets(1);
372   EXPECT_EQ(2, SendAvailableSendWindow());
373
374   AckNPackets(1);
375   EXPECT_EQ(2, SendAvailableSendWindow());
376
377   // The window should not have changed.
378   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
379
380   // Exit recovery and return to sending at the new rate.
381   for (int i = 0; i < kNumberOfAcks; ++i) {
382     AckNPackets(1);
383     EXPECT_EQ(1, SendAvailableSendWindow());
384   }
385 }
386
387 TEST_F(TcpCubicSenderTest, RTOCongestionWindow) {
388   EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
389
390   // Expect the window to decrease to the minimum once the RTO fires.
391   sender_->OnRetransmissionTimeout(true);
392   EXPECT_EQ(2 * kDefaultTCPMSS, sender_->SendWindow());
393 }
394
395 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
396   EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
397
398   // Expect the window to remain unchanged if the RTO fires but no
399   // packets are retransmitted.
400   sender_->OnRetransmissionTimeout(false);
401   EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
402 }
403
404 TEST_F(TcpCubicSenderTest, RetransmissionDelay) {
405   const int64 kRttMs = 10;
406   const int64 kDeviationMs = 3;
407   EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
408
409   sender_->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs));
410
411   // Initial value is to set the median deviation to half of the initial
412   // rtt, the median in then multiplied by a factor of 4 and finally the
413   // smoothed rtt is added which is the initial rtt.
414   QuicTime::Delta expected_delay =
415       QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
416   EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
417
418   for (int i = 0; i < 100; ++i) {
419     // Run to make sure that we converge.
420     sender_->UpdateRtt(
421         QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs));
422     sender_->UpdateRtt(
423         QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs));
424   }
425   expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
426
427   EXPECT_NEAR(kRttMs, sender_->SmoothedRtt().ToMilliseconds(), 1);
428   EXPECT_NEAR(expected_delay.ToMilliseconds(),
429               sender_->RetransmissionDelay().ToMilliseconds(),
430               1);
431   EXPECT_EQ(static_cast<int64>(
432                 sender_->GetCongestionWindow() * kNumMicrosPerSecond /
433                 sender_->SmoothedRtt().ToMicroseconds()),
434             sender_->BandwidthEstimate().ToBytesPerSecond());
435 }
436
437 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) {
438   const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
439   const int kNumberOfAcks = 100;
440   sender_.reset(
441       new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
442
443   QuicCongestionFeedbackFrame feedback;
444   // At startup make sure we can send.
445   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
446       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
447   // Get default QuicCongestionFeedbackFrame from receiver.
448   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
449   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
450                                                  not_used_);
451   // Make sure we can send.
452   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
453       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
454
455   for (int i = 0; i < kNumberOfAcks; ++i) {
456     // Send our full send window.
457     SendAvailableSendWindow();
458     AckNPackets(2);
459   }
460   QuicByteCount expected_send_window =
461       kMaxCongestionWindowTCP * kDefaultTCPMSS;
462   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
463 }
464
465 TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) {
466   const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
467   const int kNumberOfAcks = 1000;
468   sender_.reset(
469       new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP));
470
471   QuicCongestionFeedbackFrame feedback;
472   // At startup make sure we can send.
473   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
474       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
475   // Get default QuicCongestionFeedbackFrame from receiver.
476   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
477   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
478                                                  not_used_);
479   // Make sure we can send.
480   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
481       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
482
483   SendAvailableSendWindow();
484   AckNPackets(2);
485   // Make sure we fall out of slow start.
486   sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
487
488   for (int i = 0; i < kNumberOfAcks; ++i) {
489     // Send our full send window.
490     SendAvailableSendWindow();
491     AckNPackets(2);
492   }
493
494   QuicByteCount expected_send_window =
495       kMaxCongestionWindowTCP * kDefaultTCPMSS;
496   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
497 }
498
499 TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) {
500   const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
501   // Set to 10000 to compensate for small cubic alpha.
502   const int kNumberOfAcks = 10000;
503
504   sender_.reset(
505       new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
506
507   QuicCongestionFeedbackFrame feedback;
508   // At startup make sure we can send.
509   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
510       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
511   // Get default QuicCongestionFeedbackFrame from receiver.
512   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
513   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(),
514                                                  not_used_);
515   // Make sure we can send.
516   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
517       NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
518
519   SendAvailableSendWindow();
520   AckNPackets(2);
521   // Make sure we fall out of slow start.
522   sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
523
524   for (int i = 0; i < kNumberOfAcks; ++i) {
525     // Send our full send window.
526     SendAvailableSendWindow();
527     AckNPackets(2);
528   }
529
530   QuicByteCount expected_send_window =
531       kMaxCongestionWindowTCP * kDefaultTCPMSS;
532   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
533 }
534
535 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
536   SendAvailableSendWindow();
537   const QuicByteCount initial_window = sender_->GetCongestionWindow();
538   sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
539   const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
540   EXPECT_GT(initial_window, post_loss_window);
541   sender_->OnPacketLost(acked_sequence_number_ + 3, clock_.Now());
542   EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
543   sender_->OnPacketLost(sequence_number_ - 1, clock_.Now());
544   EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
545
546   // Lose a later packet and ensure the window decreases.
547   sender_->OnPacketLost(sequence_number_, clock_.Now());
548   EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
549 }
550
551 TEST_F(TcpCubicSenderTest, SendWindowNotAffectedByAcks) {
552   QuicByteCount send_window = sender_->AvailableSendWindow();
553
554   // Send a packet with no retransmittable data, and ensure that the congestion
555   // window doesn't change.
556   QuicByteCount bytes_in_packet = min(kDefaultTCPMSS, send_window);
557   sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet,
558                         NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
559   EXPECT_EQ(send_window, sender_->AvailableSendWindow());
560
561   // Send a data packet with retransmittable data, and ensure that the
562   // congestion window has shrunk.
563   sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet,
564                         NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
565   EXPECT_GT(send_window, sender_->AvailableSendWindow());
566 }
567
568 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) {
569   QuicTcpCongestionWindow congestion_window = sender_->congestion_window();
570   QuicConfig config;
571   config.set_server_initial_congestion_window(2 * congestion_window,
572                                               2 * congestion_window);
573   EXPECT_EQ(2 * congestion_window, config.server_initial_congestion_window());
574
575   sender_->SetFromConfig(config, true);
576   EXPECT_EQ(2 * congestion_window, sender_->congestion_window());
577 }
578
579 }  // namespace test
580 }  // namespace net