| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "net/quic/congestion_control/rtt_stats.h" |
| 9 #include "net/quic/congestion_control/tcp_cubic_sender.h" | 10 #include "net/quic/congestion_control/tcp_cubic_sender.h" |
| 10 #include "net/quic/congestion_control/tcp_receiver.h" | 11 #include "net/quic/congestion_control/tcp_receiver.h" |
| 11 #include "net/quic/test_tools/mock_clock.h" | 12 #include "net/quic/test_tools/mock_clock.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 14 |
| 14 using std::min; | 15 using std::min; |
| 15 | 16 |
| 16 namespace net { | 17 namespace net { |
| 17 namespace test { | 18 namespace test { |
| 18 | 19 |
| 19 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; | 20 const uint32 kDefaultWindowTCP = 10 * kDefaultTCPMSS; |
| 20 | 21 |
| 21 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. | 22 // TODO(ianswett): Remove 10000 once b/10075719 is fixed. |
| 22 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; | 23 const QuicTcpCongestionWindow kDefaultMaxCongestionWindowTCP = 10000; |
| 23 | 24 |
| 24 class TcpCubicSenderPeer : public TcpCubicSender { | 25 class TcpCubicSenderPeer : public TcpCubicSender { |
| 25 public: | 26 public: |
| 26 TcpCubicSenderPeer(const QuicClock* clock, | 27 TcpCubicSenderPeer(const QuicClock* clock, |
| 27 bool reno, | 28 bool reno, |
| 28 QuicTcpCongestionWindow max_tcp_congestion_window) | 29 QuicTcpCongestionWindow max_tcp_congestion_window) |
| 29 : TcpCubicSender(clock, reno, max_tcp_congestion_window, &stats_) { | 30 : TcpCubicSender( |
| 31 clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) { |
| 30 } | 32 } |
| 31 | 33 |
| 32 QuicTcpCongestionWindow congestion_window() { | 34 QuicTcpCongestionWindow congestion_window() { |
| 33 return congestion_window_; | 35 return congestion_window_; |
| 34 } | 36 } |
| 35 | 37 |
| 38 RttStats rtt_stats_; |
| 36 QuicConnectionStats stats_; | 39 QuicConnectionStats stats_; |
| 37 | 40 |
| 38 using TcpCubicSender::AvailableSendWindow; | 41 using TcpCubicSender::AvailableSendWindow; |
| 39 using TcpCubicSender::SendWindow; | 42 using TcpCubicSender::SendWindow; |
| 40 }; | 43 }; |
| 41 | 44 |
| 42 class TcpCubicSenderTest : public ::testing::Test { | 45 class TcpCubicSenderTest : public ::testing::Test { |
| 43 protected: | 46 protected: |
| 44 TcpCubicSenderTest() | 47 TcpCubicSenderTest() |
| 45 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 48 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 60 sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS, | 63 sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS, |
| 61 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); | 64 NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA); |
| 62 ++packets_sent; | 65 ++packets_sent; |
| 63 can_send = sender_->TimeUntilSend( | 66 can_send = sender_->TimeUntilSend( |
| 64 clock_.Now(), NOT_RETRANSMISSION, | 67 clock_.Now(), NOT_RETRANSMISSION, |
| 65 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero(); | 68 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero(); |
| 66 } | 69 } |
| 67 return packets_sent; | 70 return packets_sent; |
| 68 } | 71 } |
| 69 | 72 |
| 73 void UpdateRtt(QuicTime::Delta rtt) { |
| 74 sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero()); |
| 75 sender_->UpdateRtt(rtt); |
| 76 } |
| 77 |
| 70 // Normal is that TCP acks every other segment. | 78 // Normal is that TCP acks every other segment. |
| 71 void AckNPackets(int n) { | 79 void AckNPackets(int n) { |
| 72 for (int i = 0; i < n; ++i) { | 80 for (int i = 0; i < n; ++i) { |
| 73 ++acked_sequence_number_; | 81 ++acked_sequence_number_; |
| 74 sender_->UpdateRtt(QuicTime::Delta::FromMilliseconds(60)); | 82 UpdateRtt(QuicTime::Delta::FromMilliseconds(60)); |
| 75 sender_->OnPacketAcked(acked_sequence_number_, kDefaultTCPMSS); | 83 sender_->OnPacketAcked(acked_sequence_number_, kDefaultTCPMSS); |
| 76 } | 84 } |
| 77 clock_.AdvanceTime(one_ms_); // 1 millisecond. | 85 clock_.AdvanceTime(one_ms_); // 1 millisecond. |
| 78 } | 86 } |
| 79 | 87 |
| 80 void LoseNPackets(int n) { | 88 void LoseNPackets(int n) { |
| 81 for (int i = 0; i < n; ++i) { | 89 for (int i = 0; i < n; ++i) { |
| 82 ++acked_sequence_number_; | 90 ++acked_sequence_number_; |
| 83 sender_->OnPacketAbandoned(acked_sequence_number_, kDefaultTCPMSS); | 91 sender_->OnPacketAbandoned(acked_sequence_number_, kDefaultTCPMSS); |
| 84 sender_->OnPacketLost(acked_sequence_number_, clock_.Now()); | 92 sender_->OnPacketLost(acked_sequence_number_, clock_.Now()); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 // packets are retransmitted. | 402 // packets are retransmitted. |
| 395 sender_->OnRetransmissionTimeout(false); | 403 sender_->OnRetransmissionTimeout(false); |
| 396 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); | 404 EXPECT_EQ(kDefaultWindowTCP, sender_->SendWindow()); |
| 397 } | 405 } |
| 398 | 406 |
| 399 TEST_F(TcpCubicSenderTest, RetransmissionDelay) { | 407 TEST_F(TcpCubicSenderTest, RetransmissionDelay) { |
| 400 const int64 kRttMs = 10; | 408 const int64 kRttMs = 10; |
| 401 const int64 kDeviationMs = 3; | 409 const int64 kDeviationMs = 3; |
| 402 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); | 410 EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay()); |
| 403 | 411 |
| 404 sender_->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs)); | 412 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs)); |
| 405 | 413 |
| 406 // Initial value is to set the median deviation to half of the initial | 414 // Initial value is to set the median deviation to half of the initial |
| 407 // rtt, the median in then multiplied by a factor of 4 and finally the | 415 // rtt, the median in then multiplied by a factor of 4 and finally the |
| 408 // smoothed rtt is added which is the initial rtt. | 416 // smoothed rtt is added which is the initial rtt. |
| 409 QuicTime::Delta expected_delay = | 417 QuicTime::Delta expected_delay = |
| 410 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); | 418 QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4); |
| 411 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); | 419 EXPECT_EQ(expected_delay, sender_->RetransmissionDelay()); |
| 412 | 420 |
| 413 for (int i = 0; i < 100; ++i) { | 421 for (int i = 0; i < 100; ++i) { |
| 414 // Run to make sure that we converge. | 422 // Run to make sure that we converge. |
| 415 sender_->UpdateRtt( | 423 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); |
| 416 QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs)); | 424 UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); |
| 417 sender_->UpdateRtt( | |
| 418 QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs)); | |
| 419 } | 425 } |
| 420 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); | 426 expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4); |
| 421 | 427 |
| 422 EXPECT_NEAR(kRttMs, sender_->SmoothedRtt().ToMilliseconds(), 1); | 428 EXPECT_NEAR(kRttMs, sender_->rtt_stats_.SmoothedRtt().ToMilliseconds(), 1); |
| 423 EXPECT_NEAR(expected_delay.ToMilliseconds(), | 429 EXPECT_NEAR(expected_delay.ToMilliseconds(), |
| 424 sender_->RetransmissionDelay().ToMilliseconds(), | 430 sender_->RetransmissionDelay().ToMilliseconds(), |
| 425 1); | 431 1); |
| 426 EXPECT_EQ(static_cast<int64>( | 432 EXPECT_EQ(static_cast<int64>( |
| 427 sender_->GetCongestionWindow() * kNumMicrosPerSecond / | 433 sender_->GetCongestionWindow() * kNumMicrosPerSecond / |
| 428 sender_->SmoothedRtt().ToMicroseconds()), | 434 sender_->rtt_stats_.SmoothedRtt().ToMicroseconds()), |
| 429 sender_->BandwidthEstimate().ToBytesPerSecond()); | 435 sender_->BandwidthEstimate().ToBytesPerSecond()); |
| 430 } | 436 } |
| 431 | 437 |
| 432 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { | 438 TEST_F(TcpCubicSenderTest, SlowStartMaxSendWindow) { |
| 433 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; | 439 const QuicTcpCongestionWindow kMaxCongestionWindowTCP = 50; |
| 434 const int kNumberOfAcks = 100; | 440 const int kNumberOfAcks = 100; |
| 435 sender_.reset( | 441 sender_.reset( |
| 436 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); | 442 new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP)); |
| 437 | 443 |
| 438 QuicCongestionFeedbackFrame feedback; | 444 QuicCongestionFeedbackFrame feedback; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 } | 620 } |
| 615 | 621 |
| 616 // Next ack should cause congestion window to grow by 1MSS. | 622 // Next ack should cause congestion window to grow by 1MSS. |
| 617 AckNPackets(2); | 623 AckNPackets(2); |
| 618 expected_send_window += kDefaultTCPMSS; | 624 expected_send_window += kDefaultTCPMSS; |
| 619 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); | 625 EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); |
| 620 } | 626 } |
| 621 | 627 |
| 622 } // namespace test | 628 } // namespace test |
| 623 } // namespace net | 629 } // namespace net |
| OLD | NEW |