1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/quic_sustained_bandwidth_recorder.h"
6 
7 #include "quiche/quic/core/quic_bandwidth.h"
8 #include "quiche/quic/core/quic_time.h"
9 #include "quiche/quic/platform/api/quic_test.h"
10 
11 namespace quic {
12 namespace test {
13 namespace {
14 
15 class QuicSustainedBandwidthRecorderTest : public QuicTest {};
16 
TEST_F(QuicSustainedBandwidthRecorderTest,BandwidthEstimates)17 TEST_F(QuicSustainedBandwidthRecorderTest, BandwidthEstimates) {
18   QuicSustainedBandwidthRecorder recorder;
19   EXPECT_FALSE(recorder.HasEstimate());
20 
21   QuicTime estimate_time = QuicTime::Zero();
22   QuicWallTime wall_time = QuicWallTime::Zero();
23   QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
24   const int kBandwidthBitsPerSecond = 12345678;
25   QuicBandwidth bandwidth =
26       QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
27 
28   bool in_recovery = false;
29   bool in_slow_start = false;
30 
31   // This triggers recording, but should not yield a valid estimate yet.
32   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
33                           wall_time, srtt);
34   EXPECT_FALSE(recorder.HasEstimate());
35 
36   // Send a second reading, again this should not result in a valid estimate,
37   // as not enough time has passed.
38   estimate_time = estimate_time + srtt;
39   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
40                           wall_time, srtt);
41   EXPECT_FALSE(recorder.HasEstimate());
42 
43   // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
44   estimate_time = estimate_time + srtt;
45   estimate_time = estimate_time + srtt;
46   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
47                           wall_time, srtt);
48   EXPECT_TRUE(recorder.HasEstimate());
49   EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
50   EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
51 
52   // Resetting, and sending a different estimate will only change output after
53   // a further 3 * kSRTT has passed.
54   QuicBandwidth second_bandwidth =
55       QuicBandwidth::FromBitsPerSecond(2 * kBandwidthBitsPerSecond);
56   // Reset the recorder by passing in a measurement while in recovery.
57   in_recovery = true;
58   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
59                           wall_time, srtt);
60   in_recovery = false;
61   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
62                           wall_time, srtt);
63   EXPECT_EQ(recorder.BandwidthEstimate(), bandwidth);
64 
65   estimate_time = estimate_time + 3 * srtt;
66   const int64_t kSeconds = 556677;
67   QuicWallTime second_bandwidth_wall_time =
68       QuicWallTime::FromUNIXSeconds(kSeconds);
69   recorder.RecordEstimate(in_recovery, in_slow_start, second_bandwidth,
70                           estimate_time, second_bandwidth_wall_time, srtt);
71   EXPECT_EQ(recorder.BandwidthEstimate(), second_bandwidth);
72   EXPECT_EQ(recorder.BandwidthEstimate(), recorder.MaxBandwidthEstimate());
73   EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
74 
75   // Reset again, this time recording a lower bandwidth than before.
76   QuicBandwidth third_bandwidth =
77       QuicBandwidth::FromBitsPerSecond(0.5 * kBandwidthBitsPerSecond);
78   // Reset the recorder by passing in an unreliable measurement.
79   recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
80                           estimate_time, wall_time, srtt);
81   recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
82                           estimate_time, wall_time, srtt);
83   EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
84 
85   estimate_time = estimate_time + 3 * srtt;
86   recorder.RecordEstimate(in_recovery, in_slow_start, third_bandwidth,
87                           estimate_time, wall_time, srtt);
88   EXPECT_EQ(recorder.BandwidthEstimate(), third_bandwidth);
89 
90   // Max bandwidth should not have changed.
91   EXPECT_LT(third_bandwidth, second_bandwidth);
92   EXPECT_EQ(recorder.MaxBandwidthEstimate(), second_bandwidth);
93   EXPECT_EQ(recorder.MaxBandwidthTimestamp(), kSeconds);
94 }
95 
TEST_F(QuicSustainedBandwidthRecorderTest,SlowStart)96 TEST_F(QuicSustainedBandwidthRecorderTest, SlowStart) {
97   // Verify that slow start status is correctly recorded.
98   QuicSustainedBandwidthRecorder recorder;
99   EXPECT_FALSE(recorder.HasEstimate());
100 
101   QuicTime estimate_time = QuicTime::Zero();
102   QuicWallTime wall_time = QuicWallTime::Zero();
103   QuicTime::Delta srtt = QuicTime::Delta::FromMilliseconds(150);
104   const int kBandwidthBitsPerSecond = 12345678;
105   QuicBandwidth bandwidth =
106       QuicBandwidth::FromBitsPerSecond(kBandwidthBitsPerSecond);
107 
108   bool in_recovery = false;
109   bool in_slow_start = true;
110 
111   // This triggers recording, but should not yield a valid estimate yet.
112   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
113                           wall_time, srtt);
114 
115   // Now 3 * kSRTT has elapsed since first recording, expect a valid estimate.
116   estimate_time = estimate_time + 3 * srtt;
117   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
118                           wall_time, srtt);
119   EXPECT_TRUE(recorder.HasEstimate());
120   EXPECT_TRUE(recorder.EstimateRecordedDuringSlowStart());
121 
122   // Now send another estimate, this time not in slow start.
123   estimate_time = estimate_time + 3 * srtt;
124   in_slow_start = false;
125   recorder.RecordEstimate(in_recovery, in_slow_start, bandwidth, estimate_time,
126                           wall_time, srtt);
127   EXPECT_TRUE(recorder.HasEstimate());
128   EXPECT_FALSE(recorder.EstimateRecordedDuringSlowStart());
129 }
130 
131 }  // namespace
132 }  // namespace test
133 }  // namespace quic
134