stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 1 | /* |
| 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 Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #include "modules/pacing/bitrate_prober.h" |
Jonas Olsson | a4d8737 | 2019-07-05 19:08:33 +0200 | [diff] [blame] | 12 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 13 | #include <algorithm> |
| 14 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 15 | #include "test/gtest.h" |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 16 | |
| 17 | namespace webrtc { |
| 18 | |
| 19 | TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 20 | const FieldTrialBasedConfig config; |
| 21 | BitrateProber prober(config); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 22 | EXPECT_FALSE(prober.IsProbing()); |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 23 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 24 | Timestamp now = Timestamp::ms(0); |
| 25 | const Timestamp start_time = now; |
| 26 | EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 27 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 28 | const DataRate kTestBitrate1 = DataRate::kbps(900); |
| 29 | const DataRate kTestBitrate2 = DataRate::kbps(1800); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 30 | const int kClusterSize = 5; |
| 31 | const int kProbeSize = 1000; |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 32 | const TimeDelta kMinProbeDuration = TimeDelta::ms(15); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 33 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 34 | prober.CreateProbeCluster(kTestBitrate1, now, 0); |
| 35 | prober.CreateProbeCluster(kTestBitrate2, now, 1); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 36 | EXPECT_FALSE(prober.IsProbing()); |
| 37 | |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 38 | prober.OnIncomingPacket(kProbeSize); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 39 | EXPECT_TRUE(prober.IsProbing()); |
philipel | c7bf32a | 2017-02-17 03:59:43 -0800 | [diff] [blame] | 40 | EXPECT_EQ(0, prober.CurrentCluster().probe_cluster_id); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 41 | |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 42 | // First packet should probe as soon as possible. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 43 | EXPECT_EQ(Timestamp::MinusInfinity(), prober.NextProbeTime(now)); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 44 | |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 45 | for (int i = 0; i < kClusterSize; ++i) { |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 46 | now = std::max(now, prober.NextProbeTime(now)); |
| 47 | EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); |
philipel | c7bf32a | 2017-02-17 03:59:43 -0800 | [diff] [blame] | 48 | EXPECT_EQ(0, prober.CurrentCluster().probe_cluster_id); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 49 | prober.ProbeSent(now, kProbeSize); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 50 | } |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 51 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 52 | EXPECT_GE(now - start_time, kMinProbeDuration); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 53 | // Verify that the actual bitrate is withing 10% of the target. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 54 | DataRate bitrate = |
| 55 | DataSize::bytes(kProbeSize * (kClusterSize - 1)) / (now - start_time); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 56 | EXPECT_GT(bitrate, kTestBitrate1 * 0.9); |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 57 | EXPECT_LT(bitrate, kTestBitrate1 * 1.1); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 58 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 59 | now = std::max(now, prober.NextProbeTime(now)); |
| 60 | Timestamp probe2_started = now; |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 61 | |
| 62 | for (int i = 0; i < kClusterSize; ++i) { |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 63 | now = std::max(now, prober.NextProbeTime(now)); |
| 64 | EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); |
philipel | c7bf32a | 2017-02-17 03:59:43 -0800 | [diff] [blame] | 65 | EXPECT_EQ(1, prober.CurrentCluster().probe_cluster_id); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 66 | prober.ProbeSent(now, kProbeSize); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 67 | } |
| 68 | |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 69 | // Verify that the actual bitrate is withing 10% of the target. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 70 | TimeDelta duration = now - probe2_started; |
| 71 | EXPECT_GE(duration, kMinProbeDuration); |
| 72 | bitrate = DataSize::bytes(kProbeSize * (kClusterSize - 1)) / duration; |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 73 | EXPECT_GT(bitrate, kTestBitrate2 * 0.9); |
Yves Gerey | 665174f | 2018-06-19 15:03:05 +0200 | [diff] [blame] | 74 | EXPECT_LT(bitrate, kTestBitrate2 * 1.1); |
sergeyu | 6dbbd89 | 2017-01-17 15:07:59 -0800 | [diff] [blame] | 75 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 76 | EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 77 | EXPECT_FALSE(prober.IsProbing()); |
| 78 | } |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 79 | |
| 80 | TEST(BitrateProberTest, DoesntProbeWithoutRecentPackets) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 81 | const FieldTrialBasedConfig config; |
| 82 | BitrateProber prober(config); |
| 83 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 84 | Timestamp now = Timestamp::Zero(); |
| 85 | EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 86 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 87 | prober.CreateProbeCluster(DataRate::kbps(900), now, 0); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 88 | EXPECT_FALSE(prober.IsProbing()); |
| 89 | |
philipel | 4a1ec1e | 2016-08-15 11:51:06 -0700 | [diff] [blame] | 90 | prober.OnIncomingPacket(1000); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 91 | EXPECT_TRUE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 92 | EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); |
| 93 | prober.ProbeSent(now, 1000); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 94 | // Let time pass, no large enough packets put into prober. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 95 | now += TimeDelta::seconds(6); |
| 96 | EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); |
srte | adf4c16 | 2017-12-07 11:27:03 +0100 | [diff] [blame] | 97 | // 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. |
philipel | 4a1ec1e | 2016-08-15 11:51:06 -0700 | [diff] [blame] | 99 | prober.OnIncomingPacket(1000); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 100 | EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | TEST(BitrateProberTest, DoesntInitializeProbingForSmallPackets) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 104 | const FieldTrialBasedConfig config; |
| 105 | BitrateProber prober(config); |
| 106 | |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 107 | prober.SetEnabled(true); |
| 108 | EXPECT_FALSE(prober.IsProbing()); |
| 109 | |
philipel | 4a1ec1e | 2016-08-15 11:51:06 -0700 | [diff] [blame] | 110 | prober.OnIncomingPacket(100); |
Peter Boström | 0453ef8 | 2016-02-16 16:23:08 +0100 | [diff] [blame] | 111 | EXPECT_FALSE(prober.IsProbing()); |
| 112 | } |
| 113 | |
isheriff | cc5903e | 2016-10-04 08:29:38 -0700 | [diff] [blame] | 114 | TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 115 | const FieldTrialBasedConfig config; |
| 116 | BitrateProber prober(config); |
| 117 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 118 | const DataRate kHighBitrate = DataRate::kbps(10000); // 10 Mbps |
isheriff | cc5903e | 2016-10-04 08:29:38 -0700 | [diff] [blame] | 119 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 120 | prober.CreateProbeCluster(kHighBitrate, Timestamp::ms(0), /*cluster_id=*/0); |
isheriff | cc5903e | 2016-10-04 08:29:38 -0700 | [diff] [blame] | 121 | // Probe size should ensure a minimum of 1 ms interval. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 122 | EXPECT_GT(prober.RecommendedMinProbeSize(), |
| 123 | (kHighBitrate * TimeDelta::ms(1)).bytes<size_t>()); |
isheriff | cc5903e | 2016-10-04 08:29:38 -0700 | [diff] [blame] | 124 | } |
| 125 | |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 126 | TEST(BitrateProberTest, MinumumNumberOfProbingPackets) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 127 | const FieldTrialBasedConfig config; |
| 128 | BitrateProber prober(config); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 129 | // Even when probing at a low bitrate we expect a minimum number |
| 130 | // of packets to be sent. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 131 | const DataRate kBitrate = DataRate::kbps(100); |
| 132 | const int kPacketSizeBytes = 1000; |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 133 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 134 | Timestamp now = Timestamp::ms(0); |
| 135 | prober.CreateProbeCluster(kBitrate, now, 0); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 136 | prober.OnIncomingPacket(kPacketSizeBytes); |
| 137 | for (int i = 0; i < 5; ++i) { |
| 138 | EXPECT_TRUE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 139 | prober.ProbeSent(now, kPacketSizeBytes); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | EXPECT_FALSE(prober.IsProbing()); |
| 143 | } |
| 144 | |
| 145 | TEST(BitrateProberTest, ScaleBytesUsedForProbing) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 146 | const FieldTrialBasedConfig config; |
| 147 | BitrateProber prober(config); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 148 | const DataRate kBitrate = DataRate::kbps(10000); // 10 Mbps. |
| 149 | const int kPacketSizeBytes = 1000; |
| 150 | const int kExpectedBytesSent = (kBitrate * TimeDelta::ms(15)).bytes(); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 151 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 152 | Timestamp now = Timestamp::ms(0); |
| 153 | prober.CreateProbeCluster(kBitrate, now, /*cluster_id=*/0); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 154 | prober.OnIncomingPacket(kPacketSizeBytes); |
| 155 | int bytes_sent = 0; |
| 156 | while (bytes_sent < kExpectedBytesSent) { |
stefan | f00497c | 2017-01-27 02:27:33 -0800 | [diff] [blame] | 157 | ASSERT_TRUE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 158 | prober.ProbeSent(now, kPacketSizeBytes); |
philipel | fd58b61 | 2017-01-04 07:05:25 -0800 | [diff] [blame] | 159 | bytes_sent += kPacketSizeBytes; |
| 160 | } |
| 161 | |
| 162 | EXPECT_FALSE(prober.IsProbing()); |
| 163 | } |
| 164 | |
Johannes Kron | 8584667 | 2018-11-09 12:39:38 +0100 | [diff] [blame] | 165 | TEST(BitrateProberTest, HighBitrateProbing) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 166 | const FieldTrialBasedConfig config; |
| 167 | BitrateProber prober(config); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 168 | const DataRate kBitrate = DataRate::kbps(1000000); // 1 Gbps. |
| 169 | const int kPacketSizeBytes = 1000; |
| 170 | const int kExpectedBytesSent = (kBitrate * TimeDelta::ms(15)).bytes(); |
Johannes Kron | 8584667 | 2018-11-09 12:39:38 +0100 | [diff] [blame] | 171 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 172 | Timestamp now = Timestamp::ms(0); |
| 173 | prober.CreateProbeCluster(kBitrate, now, 0); |
Johannes Kron | 8584667 | 2018-11-09 12:39:38 +0100 | [diff] [blame] | 174 | prober.OnIncomingPacket(kPacketSizeBytes); |
| 175 | int bytes_sent = 0; |
| 176 | while (bytes_sent < kExpectedBytesSent) { |
| 177 | ASSERT_TRUE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 178 | prober.ProbeSent(now, kPacketSizeBytes); |
Johannes Kron | 8584667 | 2018-11-09 12:39:38 +0100 | [diff] [blame] | 179 | bytes_sent += kPacketSizeBytes; |
| 180 | } |
| 181 | |
| 182 | EXPECT_FALSE(prober.IsProbing()); |
| 183 | } |
| 184 | |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 185 | TEST(BitrateProberTest, ProbeClusterTimeout) { |
Jonas Olsson | 24923e8 | 2019-03-27 14:19:04 +0100 | [diff] [blame] | 186 | const FieldTrialBasedConfig config; |
| 187 | BitrateProber prober(config); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 188 | const DataRate kBitrate = DataRate::kbps(300); |
| 189 | const int kSmallPacketSize = 20; |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 190 | // Expecting two probe clusters of 5 packets each. |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 191 | const int kExpectedBytesSent = 20 * 2 * 5; |
| 192 | const TimeDelta kTimeout = TimeDelta::ms(5000); |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 193 | |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 194 | Timestamp now = Timestamp::ms(0); |
| 195 | prober.CreateProbeCluster(kBitrate, now, /*cluster_id=*/0); |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 196 | prober.OnIncomingPacket(kSmallPacketSize); |
| 197 | EXPECT_FALSE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 198 | now += kTimeout; |
| 199 | prober.CreateProbeCluster(kBitrate / 10, now, /*cluster_id=*/1); |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 200 | prober.OnIncomingPacket(kSmallPacketSize); |
| 201 | EXPECT_FALSE(prober.IsProbing()); |
Erik Språng | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 202 | now += TimeDelta::ms(1); |
| 203 | prober.CreateProbeCluster(kBitrate / 10, now, /*cluster_id=*/2); |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 204 | 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ång | b210eeb | 2019-11-05 11:21:48 +0100 | [diff] [blame] | 209 | prober.ProbeSent(now, kSmallPacketSize); |
Stefan Holmer | 0e3213a | 2017-02-08 15:19:05 +0100 | [diff] [blame] | 210 | bytes_sent += kSmallPacketSize; |
| 211 | } |
| 212 | |
| 213 | EXPECT_FALSE(prober.IsProbing()); |
| 214 | } |
stefan@webrtc.org | 82462aa | 2014-10-23 11:57:05 +0000 | [diff] [blame] | 215 | } // namespace webrtc |