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