12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm>
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/quic/congestion_control/rtt_stats.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/congestion_control/tcp_cubic_sender.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/congestion_control/tcp_receiver.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/quic/crypto/crypto_protocol.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/quic/quic_utils.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/mock_clock.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/test_tools/quic_config_peer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing std::make_pair;
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::min;
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS;
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// TODO(ianswett): Remove 10000 once b/10075719 is fixed.
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TcpCubicSenderPeer : public TcpCubicSender {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TcpCubicSenderPeer(const QuicClock* clock,
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     bool reno,
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     QuicTcpCongestionWindow max_tcp_congestion_window)
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : TcpCubicSender(
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicTcpCongestionWindow congestion_window() {
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return congestion_window_;
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  QuicTcpCongestionWindow slowstart_threshold() {
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return slowstart_threshold_;
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HybridSlowStart& hybrid_slow_start() const {
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return hybrid_slow_start_;
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RttStats rtt_stats_;
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicConnectionStats stats_;
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  using TcpCubicSender::SendWindow;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TcpCubicSenderTest : public ::testing::Test {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TcpCubicSenderTest()
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        sender_(new TcpCubicSenderPeer(&clock_, true,
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       kDefaultMaxCongestionWindowTCP)),
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        receiver_(new TcpReceiver()),
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        sequence_number_(1),
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        acked_sequence_number_(0),
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        bytes_in_flight_(0) {
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    standard_packet_.bytes_sent = kDefaultTCPMSS;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int SendAvailableSendWindow() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send as long as TimeUntilSend returns Zero.
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int packets_sent = 0;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool can_send = sender_->TimeUntilSend(
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    while (can_send) {
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++,
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++packets_sent;
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      bytes_in_flight_ += kDefaultTCPMSS;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      can_send = sender_->TimeUntilSend(
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return packets_sent;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normal is that TCP acks every other segment.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AckNPackets(int n) {
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                  QuicTime::Delta::Zero(),
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                  clock_.Now());
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector acked_packets;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector lost_packets;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < n; ++i) {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++acked_sequence_number_;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      acked_packets.push_back(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          make_pair(acked_sequence_number_, standard_packet_));
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->OnCongestionEvent(
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        true, bytes_in_flight_, acked_packets, lost_packets);
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bytes_in_flight_ -= n * kDefaultTCPMSS;
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    clock_.AdvanceTime(one_ms_);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void LoseNPackets(int n) {
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector acked_packets;
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector lost_packets;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int i = 0; i < n; ++i) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ++acked_sequence_number_;
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      lost_packets.push_back(
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          make_pair(acked_sequence_number_, standard_packet_));
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->OnCongestionEvent(
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        false, bytes_in_flight_, acked_packets, lost_packets);
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bytes_in_flight_ -= n * kDefaultTCPMSS;
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Does not increment acked_sequence_number_.
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void LosePacket(QuicPacketSequenceNumber sequence_number) {
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector acked_packets;
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendAlgorithmInterface::CongestionVector lost_packets;
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    lost_packets.push_back(
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        make_pair(sequence_number, standard_packet_));
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->OnCongestionEvent(
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        false, bytes_in_flight_, acked_packets, lost_packets);
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bytes_in_flight_ -= kDefaultTCPMSS;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const QuicTime::Delta one_ms_;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockClock clock_;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TcpCubicSenderPeer> sender_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TcpReceiver> receiver_;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber sequence_number_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketSequenceNumber acked_sequence_number_;
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  QuicByteCount bytes_in_flight_;
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  TransmissionInfo standard_packet_;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SimpleSender) {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // At startup make sure we are at the default.
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // At startup make sure we can send.
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     0,
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     HAS_RETRANSMITTABLE_DATA).IsZero());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we can send.
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     0,
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     HAS_RETRANSMITTABLE_DATA).IsZero());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // And that window is un-affected.
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Fill the send window with data, then verify that we can't send.
15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  SendAvailableSendWindow();
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                      sender_->GetCongestionWindow(),
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      HAS_RETRANSMITTABLE_DATA).IsZero());
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Send exactly 10 packets and ensure the CWND ends at 14 packets.
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const int kNumberOfAcks = 5;
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // At startup make sure we can send.
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      0,
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      HAS_RETRANSMITTABLE_DATA).IsZero());
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Make sure we can send.
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     0,
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     HAS_RETRANSMITTABLE_DATA).IsZero());
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  SendAvailableSendWindow();
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    AckNPackets(2);
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  QuicByteCount bytes_to_send = sender_->SendWindow();
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // It's expected 2 acks will arrive when the bytes_in_flight are greater than
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // half the CWND.
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            bytes_to_send);
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 20;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // At startup make sure we can send.
184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      0,
186e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      HAS_RETRANSMITTABLE_DATA).IsZero());
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we can send.
188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     0,
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     HAS_RETRANSMITTABLE_DATA).IsZero());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AckNPackets(2);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount bytes_to_send = sender_->SendWindow();
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAcks,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            bytes_to_send);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartAckTrain) {
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS,
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            sender_->GetSlowStartThreshold());
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure that we fall out of slow start when we send ACK train longer
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // than half the RTT, in this test case 30ms, which is more than 30 calls to
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ack2Packets in one round.
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we start at 10 packet first round will be 5 second round 10 etc
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 65;
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AckNPackets(2);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount expected_send_window =
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should now have fallen out of slow start.
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Testing Reno phase.
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We should need 140(65*2+10) ACK:ed packets before increasing window by
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // one.
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 69; ++i) {
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AckNPackets(2);
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SendAvailableSendWindow();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AckNPackets(2);
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  QuicByteCount expected_ss_tresh = expected_send_window;
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  expected_send_window += kDefaultTCPMSS;
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(expected_ss_tresh, sender_->GetSlowStartThreshold());
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(140u, sender_->slowstart_threshold());
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Now RTO and ensure slow start gets reset.
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(sender_->hybrid_slow_start().started());
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  sender_->OnRetransmissionTimeout(true);
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(sender_->hybrid_slow_start().started());
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(2 * kDefaultTCPMSS, sender_->GetCongestionWindow());
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(expected_send_window / 2 / kDefaultTCPMSS,
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            sender_->slowstart_threshold());
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Now revert the RTO and ensure the CWND and slowstart threshold revert.
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sender_->RevertRetransmissionTimeout();
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(140u, sender_->slowstart_threshold());
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 10;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AckNPackets(2);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SendAvailableSendWindow();
26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount expected_send_window = kDefaultWindowTCP +
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (kDefaultTCPMSS * 2 * kNumberOfAcks);
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Lose a packet to exit slow start.
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LoseNPackets(1);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should now have fallen out of slow start.
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We expect window to be cut in half by Reno.
26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  expected_send_window /= 2;
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Testing Reno phase.
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We need to ack half of the pending packet before we can send again.
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AckNPackets(number_of_packets_in_window);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We need to ack every packet in the window before we exit recovery.
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(1);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendAvailableSendWindow();
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We need to ack another window before we increase CWND by 1.
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < number_of_packets_in_window - 2; ++i) {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(1);
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendAvailableSendWindow();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AckNPackets(1);
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  expected_send_window += kDefaultTCPMSS;
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Now RTO and ensure slow start gets reset.
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(sender_->hybrid_slow_start().started());
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  sender_->OnRetransmissionTimeout(true);
2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(sender_->hybrid_slow_start().started());
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartPacketLossPRR) {
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test based on the first example in RFC6937.
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 5;
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send our full send window.
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(2);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SendAvailableSendWindow();
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicByteCount expected_send_window = kDefaultWindowTCP +
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (kDefaultTCPMSS * 2 * kNumberOfAcks);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoseNPackets(1);
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should now have fallen out of slow start.
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We expect window to be cut in half by Reno.
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  expected_send_window /= 2;
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Testing TCP proportional rate reduction.
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should send one packet for every two received acks over the remaining
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 18 outstanding packets.
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The number of packets before we exit recovery is the original CWND minus
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the packet that has been lost and the one which triggered the loss.
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t remaining_packets_in_recovery = number_of_packets_in_window * 2 - 1;
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) {
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(2);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(sender_->TimeUntilSend(
333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, SendAvailableSendWindow());
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We need to ack another window before we increase CWND by 1.
339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(1);
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, SendAvailableSendWindow());
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AckNPackets(1);
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  expected_send_window += kDefaultTCPMSS;
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartBurstPacketLossPRR) {
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test based on the second example in RFC6937, though we also implement
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // forward acknowledgements, so the first two incoming acks will trigger
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // PRR immediately.
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ack 10 packets in 5 acks to raise the CWND to 20, as in the example.
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 5;
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Send our full send window.
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendAvailableSendWindow();
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(2);
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendAvailableSendWindow();
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicByteCount expected_send_window = kDefaultWindowTCP +
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (kDefaultTCPMSS * 2 * kNumberOfAcks);
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ack a packet with a 15 packet gap, losing 13 of them due to FACK.
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoseNPackets(13);
368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Immediately after the loss, ensure at least one packet can be sent.
369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Losses without subsequent acks can occur with timer based loss detection.
370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(sender_->TimeUntilSend(
371010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AckNPackets(1);
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should now have fallen out of slow start.
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We expect window to be cut in half by Reno.
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  expected_send_window /= 2;
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Only 2 packets should be allowed to be sent, per PRR-SSRB
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, SendAvailableSendWindow());
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ack the next packet, which triggers another loss.
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoseNPackets(1);
384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AckNPackets(1);
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Send 2 packets to simulate PRR-SSRB.
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, SendAvailableSendWindow());
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Ack the next packet, which triggers another loss.
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoseNPackets(1);
391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AckNPackets(1);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Send 2 packets to simulate PRR-SSRB.
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, SendAvailableSendWindow());
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AckNPackets(1);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, SendAvailableSendWindow());
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AckNPackets(1);
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, SendAvailableSendWindow());
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The window should not have changed.
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Exit recovery and return to sending at the new rate.
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AckNPackets(1);
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1, SendAvailableSendWindow());
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) {
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(10000u, sender_->slowstart_threshold());
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Expect the window to decrease to the minimum once the RTO fires
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // and slow start threshold to be set to 1/2 of the CWND.
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sender_->OnRetransmissionTimeout(true);
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2 * kDefaultTCPMSS, sender_->SendWindow());
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(5u, sender_->slowstart_threshold());
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Now repair the RTO and ensure the slowstart threshold reverts.
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  sender_->RevertRetransmissionTimeout();
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(10000u, sender_->slowstart_threshold());
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Expect the window to remain unchanged if the RTO fires but no
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // packets are retransmitted.
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sender_->OnRetransmissionTimeout(false);
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow());
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(TcpCubicSenderTest, RetransmissionDelay) {
438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const int64 kRttMs = 10;
439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  const int64 kDeviationMs = 3;
440558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
441558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                QuicTime::Delta::Zero(), clock_.Now());
444558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Initial value is to set the median deviation to half of the initial
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // rtt, the median in then multiplied by a factor of 4 and finally the
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // smoothed rtt is added which is the initial rtt.
448558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  QuicTime::Delta expected_delay =
449558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
450558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(expected_delay, sender_->RetransmissionDelay());
451558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
452558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  for (int i = 0; i < 100; ++i) {
453558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Run to make sure that we converge.
454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->rtt_stats_.UpdateRtt(
455010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
456010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        QuicTime::Delta::Zero(), clock_.Now());
457010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sender_->rtt_stats_.UpdateRtt(
458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        QuicTime::Delta::Zero(), clock_.Now());
460558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
461558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
462558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1);
464558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_NEAR(expected_delay.ToMilliseconds(),
465558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch              sender_->RetransmissionDelay().ToMilliseconds(),
466558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch              1);
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(static_cast<int64>(
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                sender_->GetCongestionWindow() * kNumMicrosPerSecond /
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()),
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            sender_->BandwidthEstimate().ToBytesPerSecond());
471558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) {
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 100;
4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sender_.reset(
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    AckNPackets(2);
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount expected_send_window =
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kMaxCongestionWindowTCP * kDefaultTCPMSS;
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) {
4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 1000;
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sender_.reset(
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP));
4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SendAvailableSendWindow();
4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AckNPackets(2);
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Make sure we fall out of slow start.
498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LoseNPackets(1);
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    AckNPackets(2);
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount expected_send_window =
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kMaxCongestionWindowTCP * kDefaultTCPMSS;
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) {
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50;
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set to 10000 to compensate for small cubic alpha.
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kNumberOfAcks = 10000;
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  sender_.reset(
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
51968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SendAvailableSendWindow();
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AckNPackets(2);
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Make sure we fall out of slow start.
522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LoseNPackets(1);
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Send our full send window.
52668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SendAvailableSendWindow();
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    AckNPackets(2);
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  QuicByteCount expected_send_window =
5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kMaxCongestionWindowTCP * kDefaultTCPMSS;
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendAvailableSendWindow();
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const QuicByteCount initial_window = sender_->GetCongestionWindow();
538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LosePacket(acked_sequence_number_ + 1);
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_GT(initial_window, post_loss_window);
541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LosePacket(acked_sequence_number_ + 3);
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LosePacket(sequence_number_ - 1);
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Lose a later packet and ensure the window decreases.
547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LosePacket(sequence_number_);
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Send a packet with no retransmittable data, and ensure it's not tracked.
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     sequence_number_++, kDefaultTCPMSS,
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     NO_RETRANSMITTABLE_DATA));
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Send a data packet with retransmittable data, and ensure it is tracked.
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    sequence_number_++, kDefaultTCPMSS,
560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                    HAS_RETRANSMITTABLE_DATA));
561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) {
5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicTcpCongestionWindow congestion_window = sender_->congestion_window();
5650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  QuicConfig config;
5660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window);
5670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  sender_->SetFromConfig(config, true);
5690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(2 * congestion_window, sender_->congestion_window());
5706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify that kCOPT: kIW10 forces the congestion window to the
5726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // default of 10 regardless of ReceivedInitialWindow.
5736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  QuicTagVector options;
5746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  options.push_back(kIW10);
5756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
5766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sender_->SetFromConfig(config, true);
5776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(congestion_window, sender_->congestion_window());
5780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
5790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) {
581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ack 10 packets in 5 acks to raise the CWND to 20.
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int kNumberOfAcks = 5;
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < kNumberOfAcks; ++i) {
584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Send our full send window.
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SendAvailableSendWindow();
586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AckNPackets(2);
587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SendAvailableSendWindow();
589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicByteCount expected_send_window = kDefaultWindowTCP +
590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (kDefaultTCPMSS * 2 * kNumberOfAcks);
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LoseNPackets(1);
594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We should now have fallen out of slow start, and window should be cut in
596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // half by Reno. New cwnd should be 10.
597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  expected_send_window /= 2;
598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No congestion window growth should occur in recovery phase, i.e.,
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // until the currently outstanding 20 packets are acked.
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 10; ++i) {
603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Send our full send window.
604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SendAvailableSendWindow();
605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AckNPackets(2);
606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Out of recovery now. Congestion window should not grow during RTT.
610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 4; ++i) {
611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Send our full send window.
612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SendAvailableSendWindow();
613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AckNPackets(2);
614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Next ack should cause congestion window to grow by 1MSS.
618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AckNPackets(2);
619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  expected_send_window += kDefaultTCPMSS;
620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
625