blob: 6f3624f4ab3a5289db7da4be3a319280893353a4 [file] [log] [blame]
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001/*
2 * Copyright (c) 2014 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/pacing/bitrate_prober.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Erik Språngb210eeb2019-11-05 11:21:48 +010013#include <algorithm>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "test/gtest.h"
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000016
17namespace webrtc {
18
19TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
Jonas Olsson24923e82019-03-27 14:19:04 +010020 const FieldTrialBasedConfig config;
21 BitrateProber prober(config);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000022 EXPECT_FALSE(prober.IsProbing());
Jonas Olsson24923e82019-03-27 14:19:04 +010023
Erik Språngb210eeb2019-11-05 11:21:48 +010024 Timestamp now = Timestamp::ms(0);
25 const Timestamp start_time = now;
26 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000027
Erik Språngb210eeb2019-11-05 11:21:48 +010028 const DataRate kTestBitrate1 = DataRate::kbps(900);
29 const DataRate kTestBitrate2 = DataRate::kbps(1800);
sergeyu6dbbd892017-01-17 15:07:59 -080030 const int kClusterSize = 5;
31 const int kProbeSize = 1000;
Erik Språngb210eeb2019-11-05 11:21:48 +010032 const TimeDelta kMinProbeDuration = TimeDelta::ms(15);
sergeyu6dbbd892017-01-17 15:07:59 -080033
Erik Språngb210eeb2019-11-05 11:21:48 +010034 prober.CreateProbeCluster(kTestBitrate1, now, 0);
35 prober.CreateProbeCluster(kTestBitrate2, now, 1);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000036 EXPECT_FALSE(prober.IsProbing());
37
sergeyu6dbbd892017-01-17 15:07:59 -080038 prober.OnIncomingPacket(kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000039 EXPECT_TRUE(prober.IsProbing());
philipelc7bf32a2017-02-17 03:59:43 -080040 EXPECT_EQ(0, prober.CurrentCluster().probe_cluster_id);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000041
Peter Boström0453ef82016-02-16 16:23:08 +010042 // First packet should probe as soon as possible.
Erik Språngb210eeb2019-11-05 11:21:48 +010043 EXPECT_EQ(Timestamp::MinusInfinity(), prober.NextProbeTime(now));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000044
sergeyu6dbbd892017-01-17 15:07:59 -080045 for (int i = 0; i < kClusterSize; ++i) {
Erik Språngb210eeb2019-11-05 11:21:48 +010046 now = std::max(now, prober.NextProbeTime(now));
47 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now)));
philipelc7bf32a2017-02-17 03:59:43 -080048 EXPECT_EQ(0, prober.CurrentCluster().probe_cluster_id);
Erik Språngb210eeb2019-11-05 11:21:48 +010049 prober.ProbeSent(now, kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000050 }
sergeyu6dbbd892017-01-17 15:07:59 -080051
Erik Språngb210eeb2019-11-05 11:21:48 +010052 EXPECT_GE(now - start_time, kMinProbeDuration);
sergeyu6dbbd892017-01-17 15:07:59 -080053 // Verify that the actual bitrate is withing 10% of the target.
Erik Språngb210eeb2019-11-05 11:21:48 +010054 DataRate bitrate =
55 DataSize::bytes(kProbeSize * (kClusterSize - 1)) / (now - start_time);
sergeyu6dbbd892017-01-17 15:07:59 -080056 EXPECT_GT(bitrate, kTestBitrate1 * 0.9);
Yves Gerey665174f2018-06-19 15:03:05 +020057 EXPECT_LT(bitrate, kTestBitrate1 * 1.1);
sergeyu6dbbd892017-01-17 15:07:59 -080058
Erik Språngb210eeb2019-11-05 11:21:48 +010059 now = std::max(now, prober.NextProbeTime(now));
60 Timestamp probe2_started = now;
sergeyu6dbbd892017-01-17 15:07:59 -080061
62 for (int i = 0; i < kClusterSize; ++i) {
Erik Språngb210eeb2019-11-05 11:21:48 +010063 now = std::max(now, prober.NextProbeTime(now));
64 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now)));
philipelc7bf32a2017-02-17 03:59:43 -080065 EXPECT_EQ(1, prober.CurrentCluster().probe_cluster_id);
Erik Språngb210eeb2019-11-05 11:21:48 +010066 prober.ProbeSent(now, kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000067 }
68
sergeyu6dbbd892017-01-17 15:07:59 -080069 // Verify that the actual bitrate is withing 10% of the target.
Erik Språngb210eeb2019-11-05 11:21:48 +010070 TimeDelta duration = now - probe2_started;
71 EXPECT_GE(duration, kMinProbeDuration);
72 bitrate = DataSize::bytes(kProbeSize * (kClusterSize - 1)) / duration;
sergeyu6dbbd892017-01-17 15:07:59 -080073 EXPECT_GT(bitrate, kTestBitrate2 * 0.9);
Yves Gerey665174f2018-06-19 15:03:05 +020074 EXPECT_LT(bitrate, kTestBitrate2 * 1.1);
sergeyu6dbbd892017-01-17 15:07:59 -080075
Erik Språngb210eeb2019-11-05 11:21:48 +010076 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000077 EXPECT_FALSE(prober.IsProbing());
78}
Peter Boström0453ef82016-02-16 16:23:08 +010079
80TEST(BitrateProberTest, DoesntProbeWithoutRecentPackets) {
Jonas Olsson24923e82019-03-27 14:19:04 +010081 const FieldTrialBasedConfig config;
82 BitrateProber prober(config);
83
Erik Språngb210eeb2019-11-05 11:21:48 +010084 Timestamp now = Timestamp::Zero();
85 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity());
Peter Boström0453ef82016-02-16 16:23:08 +010086
Erik Språngb210eeb2019-11-05 11:21:48 +010087 prober.CreateProbeCluster(DataRate::kbps(900), now, 0);
Peter Boström0453ef82016-02-16 16:23:08 +010088 EXPECT_FALSE(prober.IsProbing());
89
philipel4a1ec1e2016-08-15 11:51:06 -070090 prober.OnIncomingPacket(1000);
Peter Boström0453ef82016-02-16 16:23:08 +010091 EXPECT_TRUE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +010092 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now)));
93 prober.ProbeSent(now, 1000);
Peter Boström0453ef82016-02-16 16:23:08 +010094 // Let time pass, no large enough packets put into prober.
Erik Språngb210eeb2019-11-05 11:21:48 +010095 now += TimeDelta::seconds(6);
96 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity());
srteadf4c162017-12-07 11:27:03 +010097 // Check that legacy behaviour where prober is reset in TimeUntilNextProbe is
98 // no longer there. Probes are no longer retried if they are timed out.
philipel4a1ec1e2016-08-15 11:51:06 -070099 prober.OnIncomingPacket(1000);
Erik Språngb210eeb2019-11-05 11:21:48 +0100100 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity());
Peter Boström0453ef82016-02-16 16:23:08 +0100101}
102
103TEST(BitrateProberTest, DoesntInitializeProbingForSmallPackets) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100104 const FieldTrialBasedConfig config;
105 BitrateProber prober(config);
106
Peter Boström0453ef82016-02-16 16:23:08 +0100107 prober.SetEnabled(true);
108 EXPECT_FALSE(prober.IsProbing());
109
philipel4a1ec1e2016-08-15 11:51:06 -0700110 prober.OnIncomingPacket(100);
Peter Boström0453ef82016-02-16 16:23:08 +0100111 EXPECT_FALSE(prober.IsProbing());
112}
113
isheriffcc5903e2016-10-04 08:29:38 -0700114TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100115 const FieldTrialBasedConfig config;
116 BitrateProber prober(config);
117
Erik Språngb210eeb2019-11-05 11:21:48 +0100118 const DataRate kHighBitrate = DataRate::kbps(10000); // 10 Mbps
isheriffcc5903e2016-10-04 08:29:38 -0700119
Erik Språngb210eeb2019-11-05 11:21:48 +0100120 prober.CreateProbeCluster(kHighBitrate, Timestamp::ms(0), /*cluster_id=*/0);
isheriffcc5903e2016-10-04 08:29:38 -0700121 // Probe size should ensure a minimum of 1 ms interval.
Erik Språngb210eeb2019-11-05 11:21:48 +0100122 EXPECT_GT(prober.RecommendedMinProbeSize(),
123 (kHighBitrate * TimeDelta::ms(1)).bytes<size_t>());
isheriffcc5903e2016-10-04 08:29:38 -0700124}
125
philipelfd58b612017-01-04 07:05:25 -0800126TEST(BitrateProberTest, MinumumNumberOfProbingPackets) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100127 const FieldTrialBasedConfig config;
128 BitrateProber prober(config);
philipelfd58b612017-01-04 07:05:25 -0800129 // Even when probing at a low bitrate we expect a minimum number
130 // of packets to be sent.
Erik Språngb210eeb2019-11-05 11:21:48 +0100131 const DataRate kBitrate = DataRate::kbps(100);
132 const int kPacketSizeBytes = 1000;
philipelfd58b612017-01-04 07:05:25 -0800133
Erik Språngb210eeb2019-11-05 11:21:48 +0100134 Timestamp now = Timestamp::ms(0);
135 prober.CreateProbeCluster(kBitrate, now, 0);
philipelfd58b612017-01-04 07:05:25 -0800136 prober.OnIncomingPacket(kPacketSizeBytes);
137 for (int i = 0; i < 5; ++i) {
138 EXPECT_TRUE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100139 prober.ProbeSent(now, kPacketSizeBytes);
philipelfd58b612017-01-04 07:05:25 -0800140 }
141
142 EXPECT_FALSE(prober.IsProbing());
143}
144
145TEST(BitrateProberTest, ScaleBytesUsedForProbing) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100146 const FieldTrialBasedConfig config;
147 BitrateProber prober(config);
Erik Språngb210eeb2019-11-05 11:21:48 +0100148 const DataRate kBitrate = DataRate::kbps(10000); // 10 Mbps.
149 const int kPacketSizeBytes = 1000;
150 const int kExpectedBytesSent = (kBitrate * TimeDelta::ms(15)).bytes();
philipelfd58b612017-01-04 07:05:25 -0800151
Erik Språngb210eeb2019-11-05 11:21:48 +0100152 Timestamp now = Timestamp::ms(0);
153 prober.CreateProbeCluster(kBitrate, now, /*cluster_id=*/0);
philipelfd58b612017-01-04 07:05:25 -0800154 prober.OnIncomingPacket(kPacketSizeBytes);
155 int bytes_sent = 0;
156 while (bytes_sent < kExpectedBytesSent) {
stefanf00497c2017-01-27 02:27:33 -0800157 ASSERT_TRUE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100158 prober.ProbeSent(now, kPacketSizeBytes);
philipelfd58b612017-01-04 07:05:25 -0800159 bytes_sent += kPacketSizeBytes;
160 }
161
162 EXPECT_FALSE(prober.IsProbing());
163}
164
Johannes Kron85846672018-11-09 12:39:38 +0100165TEST(BitrateProberTest, HighBitrateProbing) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100166 const FieldTrialBasedConfig config;
167 BitrateProber prober(config);
Erik Språngb210eeb2019-11-05 11:21:48 +0100168 const DataRate kBitrate = DataRate::kbps(1000000); // 1 Gbps.
169 const int kPacketSizeBytes = 1000;
170 const int kExpectedBytesSent = (kBitrate * TimeDelta::ms(15)).bytes();
Johannes Kron85846672018-11-09 12:39:38 +0100171
Erik Språngb210eeb2019-11-05 11:21:48 +0100172 Timestamp now = Timestamp::ms(0);
173 prober.CreateProbeCluster(kBitrate, now, 0);
Johannes Kron85846672018-11-09 12:39:38 +0100174 prober.OnIncomingPacket(kPacketSizeBytes);
175 int bytes_sent = 0;
176 while (bytes_sent < kExpectedBytesSent) {
177 ASSERT_TRUE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100178 prober.ProbeSent(now, kPacketSizeBytes);
Johannes Kron85846672018-11-09 12:39:38 +0100179 bytes_sent += kPacketSizeBytes;
180 }
181
182 EXPECT_FALSE(prober.IsProbing());
183}
184
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100185TEST(BitrateProberTest, ProbeClusterTimeout) {
Jonas Olsson24923e82019-03-27 14:19:04 +0100186 const FieldTrialBasedConfig config;
187 BitrateProber prober(config);
Erik Språngb210eeb2019-11-05 11:21:48 +0100188 const DataRate kBitrate = DataRate::kbps(300);
189 const int kSmallPacketSize = 20;
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100190 // Expecting two probe clusters of 5 packets each.
Erik Språngb210eeb2019-11-05 11:21:48 +0100191 const int kExpectedBytesSent = 20 * 2 * 5;
192 const TimeDelta kTimeout = TimeDelta::ms(5000);
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100193
Erik Språngb210eeb2019-11-05 11:21:48 +0100194 Timestamp now = Timestamp::ms(0);
195 prober.CreateProbeCluster(kBitrate, now, /*cluster_id=*/0);
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100196 prober.OnIncomingPacket(kSmallPacketSize);
197 EXPECT_FALSE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100198 now += kTimeout;
199 prober.CreateProbeCluster(kBitrate / 10, now, /*cluster_id=*/1);
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100200 prober.OnIncomingPacket(kSmallPacketSize);
201 EXPECT_FALSE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100202 now += TimeDelta::ms(1);
203 prober.CreateProbeCluster(kBitrate / 10, now, /*cluster_id=*/2);
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100204 prober.OnIncomingPacket(kSmallPacketSize);
205 EXPECT_TRUE(prober.IsProbing());
206 int bytes_sent = 0;
207 while (bytes_sent < kExpectedBytesSent) {
208 ASSERT_TRUE(prober.IsProbing());
Erik Språngb210eeb2019-11-05 11:21:48 +0100209 prober.ProbeSent(now, kSmallPacketSize);
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100210 bytes_sent += kSmallPacketSize;
211 }
212
213 EXPECT_FALSE(prober.IsProbing());
214}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000215} // namespace webrtc