103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/quic/quic_sustained_bandwidth_recorder.h" 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/quic/quic_bandwidth.h" 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/quic/quic_time.h" 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace net { 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace test { 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace { 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) { 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicSustainedBandwidthRecorder recorder; 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(recorder.HasEstimate()); 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime estimate_time = QuicTime::Zero(); 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicWallTime wall_time = QuicWallTime::Zero(); 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150); 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const int kBandwidthBitsPerSecond = 12345678; 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth bandwidth = 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond); 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool in_recovery = false; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool in_slow_start = false; 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This triggers recording, but should not yield a valid estimate yet. 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(recorder.HasEstimate()); 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send a second reading, again this should not result in a valid estimate, 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // as not enough time has passed. 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt); 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(recorder.HasEstimate()); 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate. 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt); 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt); 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(recorder.HasEstimate()); 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth); 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate()); 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resetting, and sending a different estimate will only change output after 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // a further 3 * kSRTT has passed. 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth second_bandwidth = 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond); 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Reset the recorder by passing in a measurement while in recovery. 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) in_recovery = true; 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) in_recovery = false; 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth); 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt.Multiply(3)); 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const int64 kSeconds = 556677; 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicWallTime second_bandwidth_wall_time = 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicWallTime::FromUNIXSeconds(kSeconds); 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth, 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time, second_bandwidth_wall_time, srtt); 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth); 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate()); 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds); 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Reset again, this time recording a lower bandwidth than before. 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth third_bandwidth = 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond); 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Reset the recorder by passing in an unreliable measurement. 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time, wall_time, srtt); 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time, wall_time, srtt); 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth); 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt.Multiply(3)); 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth, 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time, wall_time, srtt); 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth); 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Max bandwidth should not have changed. 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_LT(third_bandwidth, second_bandwidth); 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth); 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds); 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST(QuicSustainedBandwidthRecorderTest, SlowStart) { 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Verify that slow start status is correctly recorded. 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicSustainedBandwidthRecorder recorder; 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(recorder.HasEstimate()); 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime estimate_time = QuicTime::Zero(); 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicWallTime wall_time = QuicWallTime::Zero(); 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150); 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const int kBandwidthBitsPerSecond = 12345678; 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth bandwidth = 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond); 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool in_recovery = false; 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool in_slow_start = true; 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This triggers recording, but should not yield a valid estimate yet. 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate. 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt.Multiply(3)); 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(recorder.HasEstimate()); 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart()); 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Now send another estimate, this time not in slow start. 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) estimate_time = estimate_time.Add(srtt.Multiply(3)); 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) in_slow_start = false; 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time, 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) wall_time, srtt); 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(recorder.HasEstimate()); 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart()); 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace test 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace net 132