tcp_cubic_sender_test.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
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) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/congestion_control/tcp_cubic_sender.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/congestion_control/tcp_receiver.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/mock_clock.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net { 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test { 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const uint32 kDefaultWindowTCP = 10 * kMaxPacketSize; 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const QuicByteCount kNoNBytesInFlight = 0; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TcpCubicSenderPeer : public TcpCubicSender { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch TcpCubicSenderPeer(const QuicClock* clock, bool reno) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : TcpCubicSender(clock, reno) { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using TcpCubicSender::AvailableCongestionWindow; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using TcpCubicSender::CongestionWindow; 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch using TcpCubicSender::AckAccounting; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TcpCubicSenderTest : public ::testing::Test { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TcpCubicSenderTest() 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : rtt_(QuicTime::Delta::FromMilliseconds(60)), 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) one_ms_(QuicTime::Delta::FromMilliseconds(1)), 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_(new TcpCubicSenderPeer(&clock_, true)), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) receiver_(new TcpReceiver()), 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sequence_number_(1), 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) acked_sequence_number_(0) { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SendAvailableCongestionWindow() { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (bytes_to_send > 0) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOT_RETRANSMISSION); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_to_send -= bytes_in_packet; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bytes_to_send > 0) { 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Normal is that TCP acks every other segment. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AckNPackets(int n) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < n; ++i) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) acked_sequence_number_++; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clock_.AdvanceTime(one_ms_); // 1 millisecond. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicTime::Delta rtt_; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const QuicTime::Delta one_ms_; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockClock clock_; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAlgorithmInterface::SentPacketsMap not_used_; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TcpCubicSenderPeer> sender_; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TcpReceiver> receiver_; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketSequenceNumber sequence_number_; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicPacketSequenceNumber acked_sequence_number_; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SimpleSender) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At startup make sure we are at the default. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kDefaultWindowTCP, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->AvailableCongestionWindow()); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At startup make sure we can send. 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get default QuicCongestionFeedbackFrame from receiver. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) not_used_); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we can send. 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // And that window is un-affected. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A retransmitt should always retun 0. 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) IS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kNumberOfAck = 20; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At startup make sure we can send. 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get default QuicCongestionFeedbackFrame from receiver. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) not_used_); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we can send. 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int n = 0; n < kNumberOfAck; ++n) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send our full congestion window. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicByteCount bytes_to_send = sender_->CongestionWindow(); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_to_send); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure that we fall out of slow start when we send ACK train longer 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // than half the RTT, in this test case 30ms, which is more than 30 calls to 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ack2Packets in one round. 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since we start at 10 packet first round will be 5 second round 10 etc 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kNumberOfAck = 65; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At startup make sure we can send. 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get default QuicCongestionFeedbackFrame from receiver. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) not_used_); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we can send. 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int n = 0; n < kNumberOfAck; ++n) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send our full congestion window. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicByteCount expected_congestion_window = kDefaultWindowTCP + 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (kMaxPacketSize * 2 * kNumberOfAck); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We should now have fallen out of slow start. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_congestion_window += kMaxPacketSize; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Testing Reno phase. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We should need 141(65*2+1+10) ACK:ed packets before increasing window by 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // one. 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int m = 0; m < 70; ++m) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_congestion_window += kMaxPacketSize; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure that we fall out of slow start when we encounter a packet loss. 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kNumberOfAck = 10; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At startup make sure we can send. 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get default QuicCongestionFeedbackFrame from receiver. 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback)); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now(), 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) not_used_); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we can send. 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < kNumberOfAck; ++i) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send our full congestion window. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(2); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicByteCount expected_congestion_window = kDefaultWindowTCP + 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (kMaxPacketSize * 2 * kNumberOfAck); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender_->OnIncomingLoss(clock_.Now()); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure that we should not send right now. 192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsInfinite()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We should now have fallen out of slow start. 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We expect window to be cut in half. 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_congestion_window /= 2; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Testing Reno phase. 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to ack half of the pending packet before we can send agin. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int number_of_packets_in_window = expected_congestion_window / kMaxPacketSize; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(number_of_packets_in_window); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, sender_->AvailableCongestionWindow()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(1); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_congestion_window += kMaxPacketSize; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) number_of_packets_in_window++; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We should need number_of_packets_in_window ACK:ed packets before 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // increasing window by one. 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int k = 0; k < number_of_packets_in_window; ++k) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(1); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendAvailableCongestionWindow(); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AckNPackets(1); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_congestion_window += kMaxPacketSize; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(TcpCubicSenderTest, RetransmissionDelay) { 226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const int64 kRttMs = 10; 227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const int64 kDeviationMs = 3; 228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); 229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch sender_->AckAccounting(QuicTime::Delta::FromMilliseconds(kRttMs)); 231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Initial value is to set the median deviation to half of the initial 233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // rtt, the median in then multiplied by a factor of 4 and finaly the 234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // smoothed rtt is added which is the inital rtt. 235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch QuicTime::Delta expected_delay = 236558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); 237558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); 238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (int i = 0; i < 100; ++i) { 240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Run to make sure that we converge. 241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch sender_->AckAccounting( 242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch sender_->AckAccounting( 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); 247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_NEAR(kRttMs, sender_->SmoothedRtt().ToMilliseconds(), 1); 249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_NEAR(expected_delay.ToMilliseconds(), 250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch sender_->RetransmissionDelay().ToMilliseconds(), 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1); 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace test 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net 255