blob: acae78d2056c47f4c3bba1a5776f7cf6e8bbe9f8 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/logging.h"
#include "net/quic/congestion_control/inter_arrival_bitrate_ramp_up.h"
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace test {
class InterArrivalBitrateRampUpTest : public ::testing::Test {
protected:
InterArrivalBitrateRampUpTest()
: one_ms_(QuicTime::Delta::FromMilliseconds(1)),
hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
bitrate_ramp_up_(&clock_) {
}
virtual void SetUp() {
clock_.AdvanceTime(one_ms_);
}
const QuicTime::Delta one_ms_;
const QuicTime::Delta hundred_ms_;
MockClock clock_;
InterArrivalBitrateRampUp bitrate_ramp_up_;
};
TEST_F(InterArrivalBitrateRampUpTest, GoodEstimates) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(100);
QuicBandwidth available_channel_estimate =
QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(400);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// First concave growth, towards available_channel_estimate.
for (int i = 0; i < 25; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(available_channel_estimate, sent_bitrate);
EXPECT_LE(start_rate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
// First convex growth, from available_channel_estimate.
for (int j = 0; j < 25; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
// Second concave growth, towards channel_estimate.
for (int i = 0; i < 24; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
// Second convex growth, from channel_estimate.
for (int j = 0; j < 25; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 100000,
sent_bitrate.ToBytesPerSecond(), 10000);
// Verify that we increase cubic.
for (int j = 0; j < 23; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 750000,
sent_bitrate.ToBytesPerSecond(), 10000);
}
TEST_F(InterArrivalBitrateRampUpTest, GoodEstimatesLimitedSendRate) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(100);
QuicBandwidth available_channel_estimate =
QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth max_sent_rate =
QuicBandwidth::FromKBytesPerSecond(125);
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(400);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// First concave growth, towards available_channel_estimate.
// Should pass without being affected by the max_sent_rate.
for (int i = 0; i < 25; ++i) {
clock_.AdvanceTime(hundred_ms_);
// Cap our previus sent rate.
sent_bitrate = std::min(sent_bitrate, max_sent_rate);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(available_channel_estimate, sent_bitrate);
EXPECT_LE(start_rate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
// Cap our previus sent rate.
sent_bitrate = std::min(sent_bitrate, max_sent_rate);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
// First convex growth, from available_channel_estimate.
for (int j = 0; j < 25; ++j) {
clock_.AdvanceTime(hundred_ms_);
// Cap our previus sent rate.
sent_bitrate = std::min(sent_bitrate, max_sent_rate);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = std::min(sent_bitrate, max_sent_rate);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
// We expect 2 * sent_bitrate to cap the rate.
EXPECT_LE(max_sent_rate.Add(max_sent_rate), sent_bitrate);
// Remove our sent cap.
// Expect bitrate to continue to ramp from its previous rate.
for (int j = 0; j < 5; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_LE(max_sent_rate.Add(max_sent_rate), sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
TEST_F(InterArrivalBitrateRampUpTest, GoodEstimatesCloseToChannelEstimate) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(100);
QuicBandwidth available_channel_estimate =
QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(250);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// First concave growth, towards available_channel_estimate.
for (int i = 0; i < 25; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(available_channel_estimate, sent_bitrate);
EXPECT_LE(start_rate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
// First convex growth, from available_channel_estimate.
for (int j = 0; j < 15; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
// Second concave growth, towards channel_estimate.
for (int i = 0; i < 14; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
// Second convex growth, from channel_estimate.
for (int j = 0; j < 25; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 100000,
sent_bitrate.ToBytesPerSecond(), 10000);
// Verify that we increase cubic.
for (int j = 0; j < 24; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 780000,
sent_bitrate.ToBytesPerSecond(), 20000);
}
TEST_F(InterArrivalBitrateRampUpTest, UncertainEstimates) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(100);
QuicBandwidth available_channel_estimate =
QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth channel_estimate =
QuicBandwidth::FromKBytesPerSecond(400 * 0.7f);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// First concave growth, towards available_channel_estimate.
for (int i = 0; i < 20; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(available_channel_estimate, sent_bitrate);
EXPECT_LE(start_rate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
// First convex growth, from available_channel_estimate.
for (int j = 0; j < 23; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
// Second concave growth, towards channel_estimate.
for (int i = 0; i < 12; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
// Second convex growth, from channel_estimate.
for (int j = 0; j < 30; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 100000,
sent_bitrate.ToBytesPerSecond(), 10000);
// Verify that we increase cubic.
for (int j = 0; j < 23; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond() + 750000,
sent_bitrate.ToBytesPerSecond(), 20000);
}
TEST_F(InterArrivalBitrateRampUpTest, UnknownEstimates) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(100);
QuicBandwidth available_channel_estimate =
QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(400);
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
available_channel_estimate);
// First convex growth, from start_rate.
for (int j = 0; j < 20; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(start_rate, sent_bitrate);
EXPECT_GE(available_channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(available_channel_estimate.ToBytesPerSecond(),
sent_bitrate.ToBytesPerSecond(), 10000);
// Verify that we increase cubic.
for (int j = 0; j < 31; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_NEAR(channel_estimate.ToBytesPerSecond(),
sent_bitrate.ToBytesPerSecond(), 10000);
}
TEST_F(InterArrivalBitrateRampUpTest, UpdatingChannelEstimateHigher) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth available_channel_estimate = start_rate;
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(250);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// Convex growth, from available_channel_estimate.
for (int j = 0; j < 16; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
// Increse channel estimate.
channel_estimate = QuicBandwidth::FromKBytesPerSecond(300);
bitrate_ramp_up_.UpdateChannelEstimate(channel_estimate);
// Concave growth, towards channel_estimate.
for (int i = 0; i < 22; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
TEST_F(InterArrivalBitrateRampUpTest, UpdatingChannelEstimateLower) {
QuicBandwidth start_rate = QuicBandwidth::FromKBytesPerSecond(200);
QuicBandwidth available_channel_estimate = start_rate;
QuicBandwidth channel_estimate = QuicBandwidth::FromKBytesPerSecond(250);
QuicBandwidth halfway_point = available_channel_estimate.Add(
channel_estimate.Subtract(available_channel_estimate).Scale(0.5f));
QuicBandwidth sent_bitrate = QuicBandwidth::Zero();
bitrate_ramp_up_.Reset(start_rate,
available_channel_estimate,
channel_estimate);
// Convex growth, from available_channel_estimate.
for (int j = 0; j < 16; ++j) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(available_channel_estimate, sent_bitrate);
EXPECT_GE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
// Decrese channel estimate.
channel_estimate = QuicBandwidth::FromKBytesPerSecond(240);
bitrate_ramp_up_.UpdateChannelEstimate(channel_estimate);
// Concave growth, towards channel_estimate.
for (int i = 0; i < 11; ++i) {
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_GE(channel_estimate, sent_bitrate);
EXPECT_LE(halfway_point, sent_bitrate);
}
clock_.AdvanceTime(hundred_ms_);
sent_bitrate = bitrate_ramp_up_.GetNewBitrate(sent_bitrate);
EXPECT_LE(channel_estimate, sent_bitrate);
}
} // namespace test
} // namespace net