tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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