bitrate_prober_unittest.cc (17364B)
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 11 #include "modules/pacing/bitrate_prober.h" 12 13 #include <algorithm> 14 15 #include "api/field_trials.h" 16 #include "api/transport/network_types.h" 17 #include "api/units/data_rate.h" 18 #include "api/units/data_size.h" 19 #include "api/units/time_delta.h" 20 #include "api/units/timestamp.h" 21 #include "test/create_test_field_trials.h" 22 #include "test/gtest.h" 23 24 namespace webrtc { 25 26 TEST(BitrateProberTest, VerifyStatesAndTimeBetweenProbes) { 27 const FieldTrials config = CreateTestFieldTrials(); 28 BitrateProber prober(config); 29 EXPECT_FALSE(prober.is_probing()); 30 31 Timestamp now = Timestamp::Zero(); 32 const Timestamp start_time = now; 33 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); 34 35 const DataRate kTestBitrate1 = DataRate::KilobitsPerSec(900); 36 const DataRate kTestBitrate2 = DataRate::KilobitsPerSec(1800); 37 const int kClusterSize = 5; 38 const DataSize kProbeSize = DataSize::Bytes(1000); 39 const TimeDelta kMinProbeDuration = TimeDelta::Millis(15); 40 41 prober.CreateProbeCluster({.at_time = now, 42 .target_data_rate = kTestBitrate1, 43 .target_duration = TimeDelta::Millis(15), 44 .min_probe_delta = TimeDelta::Millis(2), 45 .target_probe_count = 5, 46 .id = 0}); 47 prober.CreateProbeCluster({.at_time = now, 48 .target_data_rate = kTestBitrate2, 49 .target_duration = TimeDelta::Millis(15), 50 .min_probe_delta = TimeDelta::Millis(2), 51 .target_probe_count = 5, 52 .id = 1}); 53 EXPECT_FALSE(prober.is_probing()); 54 55 prober.OnIncomingPacket(kProbeSize); 56 EXPECT_TRUE(prober.is_probing()); 57 EXPECT_EQ(0, prober.CurrentCluster(now)->probe_cluster_id); 58 59 // First packet should probe as soon as possible. 60 EXPECT_EQ(Timestamp::MinusInfinity(), prober.NextProbeTime(now)); 61 62 for (int i = 0; i < kClusterSize; ++i) { 63 now = std::max(now, prober.NextProbeTime(now)); 64 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); 65 EXPECT_EQ(0, prober.CurrentCluster(now)->probe_cluster_id); 66 prober.ProbeSent(now, kProbeSize); 67 } 68 69 EXPECT_GE(now - start_time, kMinProbeDuration); 70 // Verify that the actual bitrate is withing 10% of the target. 71 DataRate bitrate = kProbeSize * (kClusterSize - 1) / (now - start_time); 72 EXPECT_GT(bitrate, kTestBitrate1 * 0.9); 73 EXPECT_LT(bitrate, kTestBitrate1 * 1.1); 74 75 now = std::max(now, prober.NextProbeTime(now)); 76 Timestamp probe2_started = now; 77 78 for (int i = 0; i < kClusterSize; ++i) { 79 now = std::max(now, prober.NextProbeTime(now)); 80 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); 81 EXPECT_EQ(1, prober.CurrentCluster(now)->probe_cluster_id); 82 prober.ProbeSent(now, kProbeSize); 83 } 84 85 // Verify that the actual bitrate is withing 10% of the target. 86 TimeDelta duration = now - probe2_started; 87 EXPECT_GE(duration, kMinProbeDuration); 88 bitrate = (kProbeSize * (kClusterSize - 1)) / duration; 89 EXPECT_GT(bitrate, kTestBitrate2 * 0.9); 90 EXPECT_LT(bitrate, kTestBitrate2 * 1.1); 91 92 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); 93 EXPECT_FALSE(prober.is_probing()); 94 } 95 96 TEST(BitrateProberTest, DoesntProbeWithoutRecentPackets) { 97 const FieldTrials config = CreateTestFieldTrials(); 98 BitrateProber prober(config); 99 const DataSize kProbeSize = DataSize::Bytes(1000); 100 101 Timestamp now = Timestamp::Zero(); 102 EXPECT_EQ(prober.NextProbeTime(now), Timestamp::PlusInfinity()); 103 104 prober.CreateProbeCluster({.at_time = now, 105 .target_data_rate = DataRate::KilobitsPerSec(900), 106 .target_duration = TimeDelta::Millis(15), 107 .min_probe_delta = TimeDelta::Millis(2), 108 .target_probe_count = 5, 109 .id = 0}); 110 EXPECT_FALSE(prober.is_probing()); 111 112 prober.OnIncomingPacket(kProbeSize); 113 EXPECT_TRUE(prober.is_probing()); 114 EXPECT_EQ(now, std::max(now, prober.NextProbeTime(now))); 115 prober.ProbeSent(now, kProbeSize); 116 } 117 118 TEST(BitrateProberTest, DiscardsDelayedProbes) { 119 const TimeDelta kMaxProbeDelay = TimeDelta::Millis(3); 120 const FieldTrials trials = CreateTestFieldTrials( 121 "WebRTC-Bwe-ProbingBehavior/" 122 "abort_delayed_probes:1," 123 "max_probe_delay:3ms/"); 124 BitrateProber prober(trials); 125 const DataSize kProbeSize = DataSize::Bytes(1000); 126 127 Timestamp now = Timestamp::Zero(); 128 129 // Add two probe clusters. 130 prober.CreateProbeCluster({.at_time = now, 131 .target_data_rate = DataRate::KilobitsPerSec(900), 132 .target_duration = TimeDelta::Millis(15), 133 .min_probe_delta = TimeDelta::Millis(2), 134 .target_probe_count = 5, 135 .id = 0}); 136 137 prober.OnIncomingPacket(kProbeSize); 138 EXPECT_TRUE(prober.is_probing()); 139 EXPECT_EQ(prober.CurrentCluster(now)->probe_cluster_id, 0); 140 // Advance to first probe time and indicate sent probe. 141 now = std::max(now, prober.NextProbeTime(now)); 142 prober.ProbeSent(now, kProbeSize); 143 144 // Advance time 1ms past timeout for the next probe. 145 Timestamp next_probe_time = prober.NextProbeTime(now); 146 EXPECT_GT(next_probe_time, now); 147 now += next_probe_time - now + kMaxProbeDelay + TimeDelta::Millis(1); 148 149 // Still indicates the time we wanted to probe at. 150 EXPECT_EQ(prober.NextProbeTime(now), next_probe_time); 151 // First and only cluster removed due to timeout. 152 EXPECT_FALSE(prober.CurrentCluster(now).has_value()); 153 } 154 155 TEST(BitrateProberTest, LimitsNumberOfPendingProbeClusters) { 156 const FieldTrials config = CreateTestFieldTrials(); 157 BitrateProber prober(config); 158 const DataSize kProbeSize = DataSize::Bytes(1000); 159 Timestamp now = Timestamp::Zero(); 160 prober.CreateProbeCluster({.at_time = now, 161 .target_data_rate = DataRate::KilobitsPerSec(900), 162 .target_duration = TimeDelta::Millis(15), 163 .min_probe_delta = TimeDelta::Millis(2), 164 .target_probe_count = 5, 165 .id = 0}); 166 prober.OnIncomingPacket(kProbeSize); 167 ASSERT_TRUE(prober.is_probing()); 168 ASSERT_EQ(prober.CurrentCluster(now)->probe_cluster_id, 0); 169 170 for (int i = 1; i < 11; ++i) { 171 prober.CreateProbeCluster( 172 {.at_time = now, 173 .target_data_rate = DataRate::KilobitsPerSec(900), 174 .target_duration = TimeDelta::Millis(15), 175 .min_probe_delta = TimeDelta::Millis(2), 176 .target_probe_count = 5, 177 .id = i}); 178 prober.OnIncomingPacket(kProbeSize); 179 } 180 // Expect some clusters has been dropped. 181 EXPECT_TRUE(prober.is_probing()); 182 EXPECT_GE(prober.CurrentCluster(now)->probe_cluster_id, 5); 183 184 Timestamp max_expected_probe_time = now + TimeDelta::Seconds(1); 185 while (prober.is_probing() && now < max_expected_probe_time) { 186 now = std::max(now, prober.NextProbeTime(now)); 187 prober.ProbeSent(now, kProbeSize); 188 } 189 EXPECT_FALSE(prober.is_probing()); 190 } 191 192 TEST(BitrateProberTest, DoesntInitializeProbingForSmallPackets) { 193 const FieldTrials config = CreateTestFieldTrials(); 194 BitrateProber prober(config); 195 prober.SetEnabled(true); 196 ASSERT_FALSE(prober.is_probing()); 197 198 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 199 .target_data_rate = DataRate::KilobitsPerSec(1000), 200 .target_duration = TimeDelta::Millis(15), 201 .min_probe_delta = TimeDelta::Millis(2), 202 .target_probe_count = 5, 203 .id = 0}); 204 prober.OnIncomingPacket(DataSize::Bytes(100)); 205 206 EXPECT_FALSE(prober.is_probing()); 207 } 208 209 TEST(BitrateProberTest, DoesInitializeProbingForSmallPacketsIfConfigured) { 210 const FieldTrials config = CreateTestFieldTrials( 211 "WebRTC-Bwe-ProbingBehavior/" 212 "min_packet_size:0bytes/"); 213 BitrateProber prober(config); 214 prober.SetEnabled(true); 215 ASSERT_FALSE(prober.is_probing()); 216 217 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 218 .target_data_rate = DataRate::KilobitsPerSec(1000), 219 .target_duration = TimeDelta::Millis(15), 220 .min_probe_delta = TimeDelta::Millis(2), 221 .target_probe_count = 5, 222 .id = 0}); 223 prober.OnIncomingPacket(DataSize::Bytes(10)); 224 225 EXPECT_TRUE(prober.is_probing()); 226 } 227 228 TEST(BitrateProberTest, VerifyProbeSizeOnHighBitrate) { 229 const FieldTrials config = CreateTestFieldTrials(); 230 BitrateProber prober(config); 231 232 const DataRate kHighBitrate = DataRate::KilobitsPerSec(10000); // 10 Mbps 233 234 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 235 .target_data_rate = kHighBitrate, 236 .target_duration = TimeDelta::Millis(15), 237 .min_probe_delta = TimeDelta::Millis(2), 238 .target_probe_count = 5, 239 .id = 0}); 240 // Probe size should ensure a minimum of 1 ms interval. 241 EXPECT_GT(prober.RecommendedMinProbeSize(), 242 kHighBitrate * TimeDelta::Millis(1)); 243 } 244 245 TEST(BitrateProberTest, ProbeSizeCanBeSetInProbeClusterConfig) { 246 const FieldTrials config = CreateTestFieldTrials(); 247 BitrateProber prober(config); 248 prober.SetEnabled(true); 249 250 const DataRate kHighBitrate = DataRate::KilobitsPerSec(10000); // 10 Mbps 251 252 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 253 .target_data_rate = kHighBitrate, 254 .target_duration = TimeDelta::Millis(15), 255 .min_probe_delta = TimeDelta::Millis(20), 256 .target_probe_count = 5, 257 .id = 0}); 258 EXPECT_EQ(prober.RecommendedMinProbeSize(), 259 kHighBitrate * TimeDelta::Millis(20)); 260 261 prober.OnIncomingPacket(DataSize::Bytes(1000)); 262 // Next time to send probe should be "min_probe_delta" if the recommended 263 // number of bytes has been sent. 264 prober.ProbeSent(Timestamp::Zero(), prober.RecommendedMinProbeSize()); 265 EXPECT_EQ(prober.NextProbeTime(Timestamp::Zero()), 266 Timestamp::Zero() + TimeDelta::Millis(20)); 267 } 268 269 TEST(BitrateProberTest, MinumumNumberOfProbingPackets) { 270 const FieldTrials config = CreateTestFieldTrials(); 271 BitrateProber prober(config); 272 // Even when probing at a low bitrate we expect a minimum number 273 // of packets to be sent. 274 const DataRate kBitrate = DataRate::KilobitsPerSec(100); 275 const DataSize kPacketSize = DataSize::Bytes(1000); 276 277 Timestamp now = Timestamp::Zero(); 278 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 279 .target_data_rate = kBitrate, 280 .target_duration = TimeDelta::Millis(15), 281 .min_probe_delta = TimeDelta::Millis(2), 282 .target_probe_count = 5, 283 .id = 0}); 284 285 prober.OnIncomingPacket(kPacketSize); 286 for (int i = 0; i < 5; ++i) { 287 EXPECT_TRUE(prober.is_probing()); 288 prober.ProbeSent(now, kPacketSize); 289 } 290 291 EXPECT_FALSE(prober.is_probing()); 292 } 293 294 TEST(BitrateProberTest, ScaleBytesUsedForProbing) { 295 const FieldTrials config = CreateTestFieldTrials(); 296 BitrateProber prober(config); 297 const DataRate kBitrate = DataRate::KilobitsPerSec(10000); // 10 Mbps. 298 const DataSize kPacketSize = DataSize::Bytes(1000); 299 const DataSize kExpectedDataSent = kBitrate * TimeDelta::Millis(15); 300 301 Timestamp now = Timestamp::Zero(); 302 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 303 .target_data_rate = kBitrate, 304 .target_duration = TimeDelta::Millis(15), 305 .min_probe_delta = TimeDelta::Millis(2), 306 .target_probe_count = 5, 307 .id = 0}); 308 prober.OnIncomingPacket(kPacketSize); 309 DataSize data_sent = DataSize::Zero(); 310 while (data_sent < kExpectedDataSent) { 311 ASSERT_TRUE(prober.is_probing()); 312 prober.ProbeSent(now, kPacketSize); 313 data_sent += kPacketSize; 314 } 315 316 EXPECT_FALSE(prober.is_probing()); 317 } 318 319 TEST(BitrateProberTest, HighBitrateProbing) { 320 const FieldTrials config = CreateTestFieldTrials(); 321 BitrateProber prober(config); 322 const DataRate kBitrate = DataRate::KilobitsPerSec(1000000); // 1 Gbps. 323 const DataSize kPacketSize = DataSize::Bytes(1000); 324 const DataSize kExpectedDataSent = kBitrate * TimeDelta::Millis(15); 325 326 Timestamp now = Timestamp::Zero(); 327 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 328 .target_data_rate = kBitrate, 329 .target_duration = TimeDelta::Millis(15), 330 .min_probe_delta = TimeDelta::Millis(2), 331 .target_probe_count = 5, 332 .id = 0}); 333 prober.OnIncomingPacket(kPacketSize); 334 DataSize data_sent = DataSize::Zero(); 335 while (data_sent < kExpectedDataSent) { 336 ASSERT_TRUE(prober.is_probing()); 337 prober.ProbeSent(now, kPacketSize); 338 data_sent += kPacketSize; 339 } 340 341 EXPECT_FALSE(prober.is_probing()); 342 } 343 344 TEST(BitrateProberTest, ProbeClusterTimeout) { 345 const FieldTrials config = CreateTestFieldTrials(); 346 BitrateProber prober(config); 347 const DataRate kBitrate = DataRate::KilobitsPerSec(300); 348 const DataSize kSmallPacketSize = DataSize::Bytes(20); 349 // Expecting two probe clusters of 5 packets each. 350 const DataSize kExpectedDataSent = kSmallPacketSize * 2 * 5; 351 const TimeDelta kTimeout = TimeDelta::Millis(5000); 352 353 Timestamp now = Timestamp::Zero(); 354 prober.CreateProbeCluster({.at_time = now, 355 .target_data_rate = kBitrate, 356 .target_duration = TimeDelta::Millis(15), 357 .min_probe_delta = TimeDelta::Millis(2), 358 .target_probe_count = 5, 359 .id = 0}); 360 prober.OnIncomingPacket(kSmallPacketSize); 361 EXPECT_FALSE(prober.is_probing()); 362 now += kTimeout; 363 prober.CreateProbeCluster({.at_time = now, 364 .target_data_rate = kBitrate / 10, 365 .target_duration = TimeDelta::Millis(15), 366 .min_probe_delta = TimeDelta::Millis(2), 367 .target_probe_count = 5, 368 .id = 1}); 369 prober.OnIncomingPacket(kSmallPacketSize); 370 EXPECT_FALSE(prober.is_probing()); 371 now += TimeDelta::Millis(1); 372 prober.CreateProbeCluster({.at_time = now, 373 .target_data_rate = kBitrate / 10, 374 .target_duration = TimeDelta::Millis(15), 375 .min_probe_delta = TimeDelta::Millis(2), 376 .target_probe_count = 5, 377 .id = 2}); 378 prober.OnIncomingPacket(kSmallPacketSize); 379 EXPECT_TRUE(prober.is_probing()); 380 DataSize data_sent = DataSize::Zero(); 381 while (data_sent < kExpectedDataSent) { 382 ASSERT_TRUE(prober.is_probing()); 383 prober.ProbeSent(now, kSmallPacketSize); 384 data_sent += kSmallPacketSize; 385 } 386 387 EXPECT_FALSE(prober.is_probing()); 388 } 389 390 TEST(BitrateProberTest, CanProbeImmediatelyIfConfigured) { 391 const FieldTrials trials = 392 CreateTestFieldTrials("WebRTC-Bwe-ProbingBehavior/min_packet_size:0/"); 393 394 BitrateProber prober(trials); 395 prober.CreateProbeCluster({.at_time = Timestamp::Zero(), 396 .target_data_rate = DataRate::KilobitsPerSec(300), 397 .target_duration = TimeDelta::Millis(15), 398 .min_probe_delta = TimeDelta::Millis(2), 399 .target_probe_count = 5, 400 .id = 0}); 401 EXPECT_TRUE(prober.is_probing()); 402 } 403 404 TEST(BitrateProberTest, CanProbeImmediatelyAgainAfterProbeIfConfigured) { 405 const FieldTrials trials = 406 CreateTestFieldTrials("WebRTC-Bwe-ProbingBehavior/min_packet_size:0/"); 407 408 BitrateProber prober(trials); 409 ProbeClusterConfig cluster_config = { 410 .at_time = Timestamp::Zero(), 411 .target_data_rate = DataRate::KilobitsPerSec(300), 412 .target_duration = TimeDelta::Millis(15), 413 .min_probe_delta = TimeDelta::Millis(2), 414 .target_probe_count = 1, 415 .id = 0}; 416 prober.CreateProbeCluster(cluster_config); 417 ASSERT_TRUE(prober.is_probing()); 418 (cluster_config.target_data_rate * cluster_config.target_duration).bytes(); 419 prober.ProbeSent( 420 Timestamp::Zero() + TimeDelta::Millis(1), 421 cluster_config.target_data_rate * cluster_config.target_duration); 422 ASSERT_FALSE(prober.is_probing()); 423 424 cluster_config.id = 2; 425 cluster_config.at_time = Timestamp::Zero() + TimeDelta::Millis(100); 426 prober.CreateProbeCluster(cluster_config); 427 EXPECT_TRUE(prober.is_probing()); 428 } 429 430 } // namespace webrtc