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