blob: d36d8108b946427f8c155dfe6eeda0b9f3650367 [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
11#include <limits>
12
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000013#include "webrtc/modules/pacing/bitrate_prober.h"
kwibergac9f8762016-09-30 22:29:43 -070014#include "webrtc/test/gtest.h"
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000015
16namespace webrtc {
17
18TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) {
19 BitrateProber prober;
20 EXPECT_FALSE(prober.IsProbing());
21 int64_t now_ms = 0;
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +000022 EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000023
sergeyu6dbbd892017-01-17 15:07:59 -080024 const int kTestBitrate1 = 900000;
25 const int kTestBitrate2 = 1800000;
26 const int kClusterSize = 5;
27 const int kProbeSize = 1000;
28 const int kMinProbeDurationMs = 15;
29
Stefan Holmer0e3213a2017-02-08 15:19:05 +010030 prober.CreateProbeCluster(kTestBitrate1, now_ms);
31 prober.CreateProbeCluster(kTestBitrate2, now_ms);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000032 EXPECT_FALSE(prober.IsProbing());
33
sergeyu6dbbd892017-01-17 15:07:59 -080034 prober.OnIncomingPacket(kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000035 EXPECT_TRUE(prober.IsProbing());
philipeldd324862016-05-06 17:06:14 +020036 EXPECT_EQ(0, prober.CurrentClusterId());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000037
Peter Boström0453ef82016-02-16 16:23:08 +010038 // First packet should probe as soon as possible.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000039 EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000040
sergeyu6dbbd892017-01-17 15:07:59 -080041 for (int i = 0; i < kClusterSize; ++i) {
42 now_ms += prober.TimeUntilNextProbe(now_ms);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000043 EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
philipeldd324862016-05-06 17:06:14 +020044 EXPECT_EQ(0, prober.CurrentClusterId());
sergeyu6dbbd892017-01-17 15:07:59 -080045 prober.ProbeSent(now_ms, kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000046 }
sergeyu6dbbd892017-01-17 15:07:59 -080047
48 EXPECT_GE(now_ms, kMinProbeDurationMs);
49 // Verify that the actual bitrate is withing 10% of the target.
50 double bitrate = kProbeSize * (kClusterSize - 1) * 8 * 1000.0 / now_ms;
51 EXPECT_GT(bitrate, kTestBitrate1 * 0.9);
52 EXPECT_LT(bitrate, kTestBitrate1 * 1.1);
53
54 now_ms += prober.TimeUntilNextProbe(now_ms);
55 int64_t probe2_started = now_ms;
56
57 for (int i = 0; i < kClusterSize; ++i) {
58 now_ms += prober.TimeUntilNextProbe(now_ms);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000059 EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
philipeldd324862016-05-06 17:06:14 +020060 EXPECT_EQ(1, prober.CurrentClusterId());
sergeyu6dbbd892017-01-17 15:07:59 -080061 prober.ProbeSent(now_ms, kProbeSize);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000062 }
63
sergeyu6dbbd892017-01-17 15:07:59 -080064 // Verify that the actual bitrate is withing 10% of the target.
65 int duration = now_ms - probe2_started;
66 EXPECT_GE(duration, kMinProbeDurationMs);
67 bitrate = kProbeSize * (kClusterSize - 1) * 8 * 1000.0 / duration;
68 EXPECT_GT(bitrate, kTestBitrate2 * 0.9);
69 EXPECT_LT(bitrate, kTestBitrate2 * 1.1);
70
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +000071 EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000072 EXPECT_FALSE(prober.IsProbing());
73}
Peter Boström0453ef82016-02-16 16:23:08 +010074
75TEST(BitrateProberTest, DoesntProbeWithoutRecentPackets) {
76 BitrateProber prober;
77 EXPECT_FALSE(prober.IsProbing());
78 int64_t now_ms = 0;
79 EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
80
Stefan Holmer0e3213a2017-02-08 15:19:05 +010081 prober.CreateProbeCluster(900000, now_ms);
Peter Boström0453ef82016-02-16 16:23:08 +010082 EXPECT_FALSE(prober.IsProbing());
83
philipel4a1ec1e2016-08-15 11:51:06 -070084 prober.OnIncomingPacket(1000);
Peter Boström0453ef82016-02-16 16:23:08 +010085 EXPECT_TRUE(prober.IsProbing());
86 EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
isheriffcc5903e2016-10-04 08:29:38 -070087 prober.ProbeSent(now_ms, 1000);
Peter Boström0453ef82016-02-16 16:23:08 +010088 // Let time pass, no large enough packets put into prober.
89 now_ms += 6000;
90 EXPECT_EQ(-1, prober.TimeUntilNextProbe(now_ms));
Peter Boström0453ef82016-02-16 16:23:08 +010091 // Insert a large-enough packet after downtime while probing should reset to
92 // perform a new probe since the requested one didn't finish.
philipel4a1ec1e2016-08-15 11:51:06 -070093 prober.OnIncomingPacket(1000);
Peter Boström0453ef82016-02-16 16:23:08 +010094 EXPECT_EQ(0, prober.TimeUntilNextProbe(now_ms));
isheriffcc5903e2016-10-04 08:29:38 -070095 prober.ProbeSent(now_ms, 1000);
Peter Boström0453ef82016-02-16 16:23:08 +010096 // Next packet should be part of new probe and be sent with non-zero delay.
philipel4a1ec1e2016-08-15 11:51:06 -070097 prober.OnIncomingPacket(1000);
Peter Boström0453ef82016-02-16 16:23:08 +010098 EXPECT_GT(prober.TimeUntilNextProbe(now_ms), 0);
99}
100
101TEST(BitrateProberTest, DoesntInitializeProbingForSmallPackets) {
102 BitrateProber prober;
103 prober.SetEnabled(true);
104 EXPECT_FALSE(prober.IsProbing());
105
philipel4a1ec1e2016-08-15 11:51:06 -0700106 prober.OnIncomingPacket(100);
Peter Boström0453ef82016-02-16 16:23:08 +0100107 EXPECT_FALSE(prober.IsProbing());
108}
109
isheriffcc5903e2016-10-04 08:29:38 -0700110TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) {
111 BitrateProber prober;
112 constexpr unsigned kHighBitrateBps = 10000000; // 10 Mbps
113
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100114 prober.CreateProbeCluster(kHighBitrateBps, 0);
isheriffcc5903e2016-10-04 08:29:38 -0700115 // Probe size should ensure a minimum of 1 ms interval.
116 EXPECT_GT(prober.RecommendedMinProbeSize(), kHighBitrateBps / 8000);
117}
118
philipelfd58b612017-01-04 07:05:25 -0800119TEST(BitrateProberTest, MinumumNumberOfProbingPackets) {
120 BitrateProber prober;
121 // Even when probing at a low bitrate we expect a minimum number
122 // of packets to be sent.
123 constexpr int kBitrateBps = 100000; // 100 kbps
124 constexpr int kPacketSizeBytes = 1000;
125
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100126 prober.CreateProbeCluster(kBitrateBps, 0);
philipelfd58b612017-01-04 07:05:25 -0800127 prober.OnIncomingPacket(kPacketSizeBytes);
128 for (int i = 0; i < 5; ++i) {
129 EXPECT_TRUE(prober.IsProbing());
130 prober.ProbeSent(0, kPacketSizeBytes);
131 }
132
133 EXPECT_FALSE(prober.IsProbing());
134}
135
136TEST(BitrateProberTest, ScaleBytesUsedForProbing) {
137 BitrateProber prober;
138 constexpr int kBitrateBps = 10000000; // 10 Mbps
139 constexpr int kPacketSizeBytes = 1000;
140 constexpr int kExpectedBytesSent = kBitrateBps * 15 / 8000;
141
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100142 prober.CreateProbeCluster(kBitrateBps, 0);
philipelfd58b612017-01-04 07:05:25 -0800143 prober.OnIncomingPacket(kPacketSizeBytes);
144 int bytes_sent = 0;
145 while (bytes_sent < kExpectedBytesSent) {
stefanf00497c2017-01-27 02:27:33 -0800146 ASSERT_TRUE(prober.IsProbing());
philipelfd58b612017-01-04 07:05:25 -0800147 prober.ProbeSent(0, kPacketSizeBytes);
148 bytes_sent += kPacketSizeBytes;
149 }
150
151 EXPECT_FALSE(prober.IsProbing());
152}
153
Stefan Holmer0e3213a2017-02-08 15:19:05 +0100154TEST(BitrateProberTest, ProbeClusterTimeout) {
155 BitrateProber prober;
156 constexpr int kBitrateBps = 300000; // 300 kbps
157 constexpr int kSmallPacketSize = 20;
158 // Expecting two probe clusters of 5 packets each.
159 constexpr int kExpectedBytesSent = 20 * 2 * 5;
160 constexpr int64_t kTimeoutMs = 5000;
161
162 int64_t now_ms = 0;
163 prober.CreateProbeCluster(kBitrateBps, now_ms);
164 prober.OnIncomingPacket(kSmallPacketSize);
165 EXPECT_FALSE(prober.IsProbing());
166 now_ms += kTimeoutMs;
167 prober.CreateProbeCluster(kBitrateBps / 10, now_ms);
168 prober.OnIncomingPacket(kSmallPacketSize);
169 EXPECT_FALSE(prober.IsProbing());
170 now_ms += 1;
171 prober.CreateProbeCluster(kBitrateBps / 10, now_ms);
172 prober.OnIncomingPacket(kSmallPacketSize);
173 EXPECT_TRUE(prober.IsProbing());
174 int bytes_sent = 0;
175 while (bytes_sent < kExpectedBytesSent) {
176 ASSERT_TRUE(prober.IsProbing());
177 prober.ProbeSent(0, kSmallPacketSize);
178 bytes_sent += kSmallPacketSize;
179 }
180
181 EXPECT_FALSE(prober.IsProbing());
182}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000183} // namespace webrtc