1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/congestion_controller/goog_cc/trendline_estimator.h"
12
13 #include <algorithm>
14 #include <numeric>
15 #include <vector>
16
17 #include "api/transport/field_trial_based_config.h"
18 #include "rtc_base/random.h"
19 #include "test/gtest.h"
20
21 namespace webrtc {
22 namespace {
23
24 class PacketTimeGenerator {
25 public:
PacketTimeGenerator(int64_t initial_clock,double time_between_packets)26 PacketTimeGenerator(int64_t initial_clock, double time_between_packets)
27 : initial_clock_(initial_clock),
28 time_between_packets_(time_between_packets),
29 packets_(0) {}
operator ()()30 int64_t operator()() {
31 return initial_clock_ + time_between_packets_ * packets_++;
32 }
33
34 private:
35 const int64_t initial_clock_;
36 const double time_between_packets_;
37 size_t packets_;
38 };
39
40 class TrendlineEstimatorTest : public testing::Test {
41 public:
TrendlineEstimatorTest()42 TrendlineEstimatorTest()
43 : send_times(kPacketCount),
44 recv_times(kPacketCount),
45 packet_sizes(kPacketCount),
46 config(),
47 estimator(&config, nullptr),
48 count(1) {
49 std::fill(packet_sizes.begin(), packet_sizes.end(), kPacketSizeBytes);
50 }
51
RunTestUntilStateChange()52 void RunTestUntilStateChange() {
53 RTC_DCHECK_EQ(send_times.size(), kPacketCount);
54 RTC_DCHECK_EQ(recv_times.size(), kPacketCount);
55 RTC_DCHECK_EQ(packet_sizes.size(), kPacketCount);
56 RTC_DCHECK_GE(count, 1);
57 RTC_DCHECK_LT(count, kPacketCount);
58
59 auto initial_state = estimator.State();
60 for (; count < kPacketCount; count++) {
61 double recv_delta = recv_times[count] - recv_times[count - 1];
62 double send_delta = send_times[count] - send_times[count - 1];
63 estimator.Update(recv_delta, send_delta, send_times[count],
64 recv_times[count], packet_sizes[count], true);
65 if (estimator.State() != initial_state) {
66 return;
67 }
68 }
69 }
70
71 protected:
72 const size_t kPacketCount = 25;
73 const size_t kPacketSizeBytes = 1200;
74 std::vector<int64_t> send_times;
75 std::vector<int64_t> recv_times;
76 std::vector<size_t> packet_sizes;
77 const FieldTrialBasedConfig config;
78 TrendlineEstimator estimator;
79 size_t count;
80 };
81 } // namespace
82
TEST_F(TrendlineEstimatorTest,Normal)83 TEST_F(TrendlineEstimatorTest, Normal) {
84 PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
85 20 /*20 ms between sent packets*/);
86 std::generate(send_times.begin(), send_times.end(), send_time_generator);
87
88 PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
89 20 /*delivered at the same pace*/);
90 std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
91
92 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
93 RunTestUntilStateChange();
94 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
95 EXPECT_EQ(count, kPacketCount); // All packets processed
96 }
97
TEST_F(TrendlineEstimatorTest,Overusing)98 TEST_F(TrendlineEstimatorTest, Overusing) {
99 PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
100 20 /*20 ms between sent packets*/);
101 std::generate(send_times.begin(), send_times.end(), send_time_generator);
102
103 PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
104 1.1 * 20 /*10% slower delivery*/);
105 std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
106
107 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
108 RunTestUntilStateChange();
109 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
110 RunTestUntilStateChange();
111 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
112 EXPECT_EQ(count, kPacketCount); // All packets processed
113 }
114
TEST_F(TrendlineEstimatorTest,Underusing)115 TEST_F(TrendlineEstimatorTest, Underusing) {
116 PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
117 20 /*20 ms between sent packets*/);
118 std::generate(send_times.begin(), send_times.end(), send_time_generator);
119
120 PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
121 0.85 * 20 /*15% faster delivery*/);
122 std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
123
124 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
125 RunTestUntilStateChange();
126 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwUnderusing);
127 RunTestUntilStateChange();
128 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwUnderusing);
129 EXPECT_EQ(count, kPacketCount); // All packets processed
130 }
131
TEST_F(TrendlineEstimatorTest,IncludesSmallPacketsByDefault)132 TEST_F(TrendlineEstimatorTest, IncludesSmallPacketsByDefault) {
133 PacketTimeGenerator send_time_generator(123456789 /*initial clock*/,
134 20 /*20 ms between sent packets*/);
135 std::generate(send_times.begin(), send_times.end(), send_time_generator);
136
137 PacketTimeGenerator recv_time_generator(987654321 /*initial clock*/,
138 1.1 * 20 /*10% slower delivery*/);
139 std::generate(recv_times.begin(), recv_times.end(), recv_time_generator);
140
141 std::fill(packet_sizes.begin(), packet_sizes.end(), 100);
142
143 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwNormal);
144 RunTestUntilStateChange();
145 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
146 RunTestUntilStateChange();
147 EXPECT_EQ(estimator.State(), BandwidthUsage::kBwOverusing);
148 EXPECT_EQ(count, kPacketCount); // All packets processed
149 }
150
151 } // namespace webrtc
152