diff options
Diffstat (limited to 'chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc')
-rw-r--r-- | chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc | 206 |
1 files changed, 127 insertions, 79 deletions
diff --git a/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc b/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc index c7046fcb2f7..20dd6a6d316 100644 --- a/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc +++ b/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/quic/congestion_control/tcp_cubic_sender.h" + #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "net/quic/congestion_control/tcp_cubic_sender.h" #include "net/quic/congestion_control/tcp_receiver.h" #include "net/quic/test_tools/mock_clock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,7 +13,8 @@ namespace net { namespace test { -const uint32 kDefaultWindowTCP = 10 * kMaxPacketSize; +const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; + // TODO(ianswett): Remove 10000 once b/10075719 is fixed. const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; @@ -23,8 +25,13 @@ class TcpCubicSenderPeer : public TcpCubicSender { QuicTcpCongestionWindow max_tcp_congestion_window) : TcpCubicSender(clock, reno, max_tcp_congestion_window) { } - using TcpCubicSender::AvailableCongestionWindow; - using TcpCubicSender::CongestionWindow; + + QuicTcpCongestionWindow congestion_window() { + return congestion_window_; + } + + using TcpCubicSender::AvailableSendWindow; + using TcpCubicSender::SendWindow; using TcpCubicSender::AckAccounting; }; @@ -40,12 +47,12 @@ class TcpCubicSenderTest : public ::testing::Test { acked_sequence_number_(0) { } - void SendAvailableCongestionWindow() { - QuicByteCount bytes_to_send = sender_->AvailableCongestionWindow(); + void SendAvailableSendWindow() { + QuicByteCount bytes_to_send = sender_->AvailableSendWindow(); while (bytes_to_send > 0) { - QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, bytes_to_send); - sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); + QuicByteCount bytes_in_packet = std::min(kDefaultTCPMSS, bytes_to_send); + sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet, + NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); bytes_to_send -= bytes_in_packet; if (bytes_to_send > 0) { EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, @@ -57,7 +64,7 @@ class TcpCubicSenderTest : public ::testing::Test { void AckNPackets(int n) { for (int i = 0; i < n; ++i) { acked_sequence_number_++; - sender_->OnIncomingAck(acked_sequence_number_, kMaxPacketSize, rtt_); + sender_->OnPacketAcked(acked_sequence_number_, kDefaultTCPMSS, rtt_); } clock_.AdvanceTime(one_ms_); // 1 millisecond. } @@ -75,8 +82,8 @@ class TcpCubicSenderTest : public ::testing::Test { TEST_F(TcpCubicSenderTest, SimpleSender) { QuicCongestionFeedbackFrame feedback; // At startup make sure we are at the default. - EXPECT_EQ(kDefaultWindowTCP, - sender_->AvailableCongestionWindow()); + EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); + EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); // At startup make sure we can send. EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); @@ -88,11 +95,12 @@ TEST_F(TcpCubicSenderTest, SimpleSender) { EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); // And that window is un-affected. - EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableCongestionWindow()); + EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow()); + EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow()); // A retransmit should always return 0. EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), - IS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); + NACK_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); } TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { @@ -110,12 +118,12 @@ TEST_F(TcpCubicSenderTest, ExponentialSlowStart) { NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); for (int n = 0; n < kNumberOfAck; ++n) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - QuicByteCount bytes_to_send = sender_->CongestionWindow(); - EXPECT_EQ(kDefaultWindowTCP + kMaxPacketSize * 2 * kNumberOfAck, + QuicByteCount bytes_to_send = sender_->SendWindow(); + EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * kNumberOfAck, bytes_to_send); } @@ -139,31 +147,32 @@ TEST_F(TcpCubicSenderTest, SlowStartAckTrain) { NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); for (int n = 0; n < kNumberOfAck; ++n) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - QuicByteCount expected_congestion_window = - kDefaultWindowTCP + (kMaxPacketSize * 2 * kNumberOfAck); - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + QuicByteCount expected_send_window = + kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAck); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); + EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); // We should now have fallen out of slow start. - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(2); - expected_congestion_window += kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + expected_send_window += kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); // Testing Reno phase. // We should need 141(65*2+1+10) ACK:ed packets before increasing window by // one. for (int m = 0; m < 70; ++m) { - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(2); - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); } - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(2); - expected_congestion_window += kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + expected_send_window += kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); } TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { @@ -182,16 +191,16 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); for (int i = 0; i < kNumberOfAck; ++i) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - SendAvailableCongestionWindow(); - QuicByteCount expected_congestion_window = kDefaultWindowTCP + - (kMaxPacketSize * 2 * kNumberOfAck); - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + SendAvailableSendWindow(); + QuicByteCount expected_send_window = kDefaultWindowTCP + + (kDefaultTCPMSS * 2 * kNumberOfAck); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); - sender_->OnIncomingLoss(clock_.Now()); + sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); // Make sure that we should not send right now. EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, @@ -199,32 +208,40 @@ TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) { // We should now have fallen out of slow start. // We expect window to be cut in half. - expected_congestion_window /= 2; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + expected_send_window /= 2; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); // Testing Reno phase. // We need to ack half of the pending packet before we can send again. - int number_of_packets_in_window = expected_congestion_window / kMaxPacketSize; + int number_of_packets_in_window = expected_send_window / kDefaultTCPMSS; AckNPackets(number_of_packets_in_window); - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); - EXPECT_EQ(0u, sender_->AvailableCongestionWindow()); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); + EXPECT_EQ(0u, sender_->AvailableSendWindow()); AckNPackets(1); - expected_congestion_window += kMaxPacketSize; + expected_send_window += kDefaultTCPMSS; number_of_packets_in_window++; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); // We should need number_of_packets_in_window ACK:ed packets before // increasing window by one. for (int k = 0; k < number_of_packets_in_window; ++k) { - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(1); - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + EXPECT_EQ(expected_send_window, sender_->SendWindow()); } - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(1); - expected_congestion_window += kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + expected_send_window += kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); +} + +TEST_F(TcpCubicSenderTest, RTOCongestionWindow) { + EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); + + // Expect the window to decrease to the minimum once the RTO fires. + sender_->OnRetransmissionTimeout(); + EXPECT_EQ(2 * kDefaultTCPMSS, sender_->SendWindow()); } TEST_F(TcpCubicSenderTest, RetransmissionDelay) { @@ -254,9 +271,13 @@ TEST_F(TcpCubicSenderTest, RetransmissionDelay) { EXPECT_NEAR(expected_delay.ToMilliseconds(), sender_->RetransmissionDelay().ToMilliseconds(), 1); + EXPECT_EQ(static_cast<int64>( + sender_->GetCongestionWindow() * kNumMicrosPerSecond / + sender_->SmoothedRtt().ToMicroseconds()), + sender_->BandwidthEstimate().ToBytesPerSecond()); } -TEST_F(TcpCubicSenderTest, SlowStartMaxCongestionWindow) { +TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; const int kNumberOfAck = 100; sender_.reset( @@ -275,13 +296,13 @@ TEST_F(TcpCubicSenderTest, SlowStartMaxCongestionWindow) { NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); for (int i = 0; i < kNumberOfAck; ++i) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - QuicByteCount expected_congestion_window = - kMaxCongestionWindowTCP * kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + QuicByteCount expected_send_window = + kMaxCongestionWindowTCP * kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); } TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { @@ -302,20 +323,20 @@ TEST_F(TcpCubicSenderTest, TcpRenoMaxCongestionWindow) { EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(2); // Make sure we fall out of slow start. - sender_->OnIncomingLoss(clock_.Now()); + sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); for (int i = 0; i < kNumberOfAck; ++i) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - QuicByteCount expected_congestion_window = - kMaxCongestionWindowTCP * kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + QuicByteCount expected_send_window = + kMaxCongestionWindowTCP * kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); } TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { @@ -336,37 +357,64 @@ TEST_F(TcpCubicSenderTest, TcpCubicMaxCongestionWindow) { EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); - SendAvailableCongestionWindow(); + SendAvailableSendWindow(); AckNPackets(2); // Make sure we fall out of slow start. - sender_->OnIncomingLoss(clock_.Now()); + sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); for (int i = 0; i < kNumberOfAck; ++i) { - // Send our full congestion window. - SendAvailableCongestionWindow(); + // Send our full send window. + SendAvailableSendWindow(); AckNPackets(2); } - QuicByteCount expected_congestion_window = - kMaxCongestionWindowTCP * kMaxPacketSize; - EXPECT_EQ(expected_congestion_window, sender_->CongestionWindow()); + QuicByteCount expected_send_window = + kMaxCongestionWindowTCP * kDefaultTCPMSS; + EXPECT_EQ(expected_send_window, sender_->SendWindow()); +} + +TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) { + SendAvailableSendWindow(); + const QuicByteCount initial_window = sender_->GetCongestionWindow(); + sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now()); + const QuicByteCount post_loss_window = sender_->GetCongestionWindow(); + EXPECT_GT(initial_window, post_loss_window); + sender_->OnPacketLost(acked_sequence_number_ + 3, clock_.Now()); + EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); + sender_->OnPacketLost(sequence_number_ - 1, clock_.Now()); + EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow()); + + // Lose a later packet and ensure the window decreases. + sender_->OnPacketLost(sequence_number_, clock_.Now()); + EXPECT_GT(post_loss_window, sender_->GetCongestionWindow()); } -TEST_F(TcpCubicSenderTest, CongestionWindowNotAffectedByAcks) { - QuicByteCount congestion_window = sender_->AvailableCongestionWindow(); +TEST_F(TcpCubicSenderTest, SendWindowNotAffectedByAcks) { + QuicByteCount send_window = sender_->AvailableSendWindow(); // Send a packet with no retransmittable data, and ensure that the congestion // window doesn't change. - QuicByteCount bytes_in_packet = std::min(kMaxPacketSize, congestion_window); - sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, - NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA); - EXPECT_EQ(congestion_window, sender_->AvailableCongestionWindow()); + QuicByteCount bytes_in_packet = std::min(kDefaultTCPMSS, send_window); + sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet, + NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA); + EXPECT_EQ(send_window, sender_->AvailableSendWindow()); // Send a data packet with retransmittable data, and ensure that the // congestion window has shrunk. - sender_->SentPacket(clock_.Now(), sequence_number_++, bytes_in_packet, - NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); - EXPECT_GT(congestion_window, sender_->AvailableCongestionWindow()); + sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet, + NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); + EXPECT_GT(send_window, sender_->AvailableSendWindow()); +} + +TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) { + QuicTcpCongestionWindow congestion_window = sender_->congestion_window(); + QuicConfig config; + config.set_server_initial_congestion_window(2 * congestion_window, + 2 * congestion_window); + EXPECT_EQ(2 * congestion_window, config.server_initial_congestion_window()); + + sender_->SetFromConfig(config, true); + EXPECT_EQ(2 * congestion_window, sender_->congestion_window()); } } // namespace test |