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