summaryrefslogtreecommitdiff
path: root/chromium/net/quic/congestion_control/tcp_cubic_sender_test.cc
diff options
context:
space:
mode:
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.cc206
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