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