// Copyright 2014 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 "net/quic/quic_sustained_bandwidth_recorder.h" #include "net/quic/quic_bandwidth.h" #include "net/quic/quic_time.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace test { namespace { TEST(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) { QuicSustainedBandwidthRecorder recorder; EXPECT_FALSE(recorder.HasEstimate()); QuicTime estimate_time = QuicTime::Zero(); QuicWallTime wall_time = QuicWallTime::Zero(); QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150); const int kBandwidthBitsPerSecond = 12345678; QuicBandwidth bandwidth = QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond); bool in_recovery = false; bool in_slow_start = false; // This triggers recording, but should not yield a valid estimate yet. recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_FALSE(recorder.HasEstimate()); // Send a second reading, again this should not result in a valid estimate, // as not enough time has passed. estimate_time = estimate_time.Add(srtt); recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_FALSE(recorder.HasEstimate()); // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate. estimate_time = estimate_time.Add(srtt); estimate_time = estimate_time.Add(srtt); recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_TRUE(recorder.HasEstimate()); EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth); EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate()); // Resetting, and sending a different estimate will only change output after // a further 3 * kSRTT has passed. QuicBandwidth second_bandwidth = QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond); // Reset the recorder by passing in a measurement while in recovery. in_recovery = true; recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); in_recovery = false; recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth); estimate_time = estimate_time.Add(srtt.Multiply(3)); const int64_t kSeconds = 556677; QuicWallTime second_bandwidth_wall_time = QuicWallTime::FromUNIXSeconds(kSeconds); recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth, estimate_time, second_bandwidth_wall_time, srtt); EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth); EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate()); EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds); // Reset again, this time recording a lower bandwidth than before. QuicBandwidth third_bandwidth = QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond); // Reset the recorder by passing in an unreliable measurement. recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, estimate_time, wall_time, srtt); recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, estimate_time, wall_time, srtt); EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth); estimate_time = estimate_time.Add(srtt.Multiply(3)); recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, estimate_time, wall_time, srtt); EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth); // Max bandwidth should not have changed. EXPECT_LT(third_bandwidth, second_bandwidth); EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth); EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds); } TEST(QuicSustainedBandwidthRecorderTest, SlowStart) { // Verify that slow start status is correctly recorded. QuicSustainedBandwidthRecorder recorder; EXPECT_FALSE(recorder.HasEstimate()); QuicTime estimate_time = QuicTime::Zero(); QuicWallTime wall_time = QuicWallTime::Zero(); QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150); const int kBandwidthBitsPerSecond = 12345678; QuicBandwidth bandwidth = QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond); bool in_recovery = false; bool in_slow_start = true; // This triggers recording, but should not yield a valid estimate yet. recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate. estimate_time = estimate_time.Add(srtt.Multiply(3)); recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_TRUE(recorder.HasEstimate()); EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart()); // Now send another estimate, this time not in slow start. estimate_time = estimate_time.Add(srtt.Multiply(3)); in_slow_start = false; recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, wall_time, srtt); EXPECT_TRUE(recorder.HasEstimate()); EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart()); } } // namespace } // namespace test } // namespace net