1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test of the full congestion control chain. 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/congestion_control/quic_congestion_manager.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/mock_clock.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using std::max; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCongestionManagerPeer : public QuicCongestionManager { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit QuicCongestionManagerPeer(const QuicClock* clock, 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CongestionFeedbackType congestion_type) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : QuicCongestionManager(clock, congestion_type) { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) using QuicCongestionManager::BandwidthEstimate; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCongestionControlTest : public ::testing::Test { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCongestionControlTest() 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : start_(clock_.ApproximateNow()) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetUpCongestionType(CongestionFeedbackType congestion_type) { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_.reset(new QuicCongestionManagerPeer(&clock_, congestion_type)); 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockClock clock_; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicTime start_; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<QuicCongestionManagerPeer> manager_; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, FixedRateSenderAPI) { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetUpCongestionType(kFixRate); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCongestionFeedbackFrame congestion_feedback; 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) congestion_feedback.type = kFixRate; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) congestion_feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(30); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingQuicCongestionFeedbackFrame(congestion_feedback, 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) clock_.Now()); 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->SentPacket(1, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40), 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) manager_->TimeUntilSend(clock_.Now(), 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(35)); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(QuicTime::Delta::Infinite(), 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) manager_->TimeUntilSend(clock_.Now(), 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(QuicTime::Delta::Infinite(), 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) manager_->TimeUntilSend(clock_.Now(), 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, FixedRatePacing) { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetUpCongestionType(kFixRate); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicAckFrame ack; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ack.received_info.largest_observed = 0; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingAckFrame(ack, clock_.Now()); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feedback.type = kFixRate; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(100); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicTime acc_advance_time(QuicTime::Zero()); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (QuicPacketSequenceNumber i = 1; i <= 100; ++i) { 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->SentPacket(i, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) clock_.AdvanceTime(advance_time); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) acc_advance_time = acc_advance_time.Add(advance_time); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Ack the packet we sent. 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ack.received_info.largest_observed = max( 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i, ack.received_info.largest_observed); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingAckFrame(ack, clock_.Now()); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1200), 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) acc_advance_time.Subtract(start_)); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, Pacing) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetUpCongestionType(kFixRate); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicAckFrame ack; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ack.received_info.largest_observed = 0; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingAckFrame(ack, clock_.Now()); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCongestionFeedbackFrame feedback; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feedback.type = kFixRate; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Test a high bitrate (8Mbit/s) to trigger pacing. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(1000); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now()); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicTime acc_advance_time(QuicTime::Zero()); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (QuicPacketSequenceNumber i = 1; i <= 100;) { 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(), 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero()); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION); 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(), 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) clock_.AdvanceTime(advance_time); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) acc_advance_time = acc_advance_time.Add(advance_time); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Ack the packets we sent. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ack.received_info.largest_observed = max( 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i - 2, ack.received_info.largest_observed); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingAckFrame(ack, clock_.Now()); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ack.received_info.largest_observed = max( 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i - 1, ack.received_info.largest_observed); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->OnIncomingAckFrame(ack, clock_.Now()); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(QuicTime::Delta::FromMilliseconds(120), 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) acc_advance_time.Subtract(start_)); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(pwestin): add TCP tests. 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(pwestin): add InterArrival tests. 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace test 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 137