/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "modules/remote_bitrate_estimator/aimd_rate_control.h"

#include <memory>

#include "api/transport/field_trial_based_config.h"
#include "api/units/data_rate.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

constexpr int64_t kClockInitialTime = 123456;

constexpr int kMinBwePeriodMs = 2000;
constexpr int kDefaultPeriodMs = 3000;
constexpr int kMaxBwePeriodMs = 50000;

// After an overuse, we back off to 85% to the received bitrate.
constexpr double kFractionAfterOveruse = 0.85;

struct AimdRateControlStates {
  std::unique_ptr<AimdRateControl> aimd_rate_control;
  std::unique_ptr<SimulatedClock> simulated_clock;
  FieldTrialBasedConfig field_trials;
};

AimdRateControlStates CreateAimdRateControlStates(bool send_side = false) {
  AimdRateControlStates states;
  states.aimd_rate_control.reset(
      new AimdRateControl(&states.field_trials, send_side));
  states.simulated_clock.reset(new SimulatedClock(kClockInitialTime));
  return states;
}
absl::optional<DataRate> OptionalRateFromOptionalBps(
    absl::optional<int> bitrate_bps) {
  if (bitrate_bps) {
    return DataRate::BitsPerSec(*bitrate_bps);
  } else {
    return absl::nullopt;
  }
}
void UpdateRateControl(const AimdRateControlStates& states,
                       const BandwidthUsage& bandwidth_usage,
                       absl::optional<uint32_t> throughput_estimate,
                       int64_t now_ms) {
  RateControlInput input(bandwidth_usage,
                         OptionalRateFromOptionalBps(throughput_estimate));
  states.aimd_rate_control->Update(&input, Timestamp::Millis(now_ms));
}
void SetEstimate(const AimdRateControlStates& states, int bitrate_bps) {
  states.aimd_rate_control->SetEstimate(DataRate::BitsPerSec(bitrate_bps),
                                        states.simulated_clock->CurrentTime());
}

}  // namespace

TEST(AimdRateControlTest, MinNearMaxIncreaseRateOnLowBandwith) {
  auto states = CreateAimdRateControlStates();
  constexpr int kBitrate = 30000;
  SetEstimate(states, kBitrate);
  EXPECT_EQ(4000,
            states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}

TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn90kbpsAnd200msRtt) {
  auto states = CreateAimdRateControlStates();
  constexpr int kBitrate = 90000;
  SetEstimate(states, kBitrate);
  EXPECT_EQ(5000,
            states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}

TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) {
  auto states = CreateAimdRateControlStates();
  constexpr int kBitrate = 60000;
  SetEstimate(states, kBitrate);
  states.aimd_rate_control->SetRtt(TimeDelta::Millis(100));
  EXPECT_EQ(5000,
            states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
}

TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) {
  // Smoothing experiment disabled
  auto states = CreateAimdRateControlStates();
  constexpr int kBitrate = 300000;
  SetEstimate(states, kBitrate);
  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_NEAR(14000,
              states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond(),
              1000);
  EXPECT_EQ(kDefaultPeriodMs,
            states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}

TEST(AimdRateControlTest, BweLimitedByAckedBitrate) {
  auto states = CreateAimdRateControlStates();
  constexpr int kAckedBitrate = 10000;
  SetEstimate(states, kAckedBitrate);
  while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime <
         20000) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  ASSERT_TRUE(states.aimd_rate_control->ValidEstimate());
  EXPECT_EQ(static_cast<uint32_t>(1.5 * kAckedBitrate + 10000),
            states.aimd_rate_control->LatestEstimate().bps());
}

TEST(AimdRateControlTest, BweNotLimitedByDecreasingAckedBitrate) {
  auto states = CreateAimdRateControlStates();
  constexpr int kAckedBitrate = 100000;
  SetEstimate(states, kAckedBitrate);
  while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime <
         20000) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  ASSERT_TRUE(states.aimd_rate_control->ValidEstimate());
  // If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x
  // what's being acked, but also shouldn't get to increase more.
  uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate().bps();
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate / 2,
                    states.simulated_clock->TimeInMilliseconds());
  uint32_t new_estimate = states.aimd_rate_control->LatestEstimate().bps();
  EXPECT_NEAR(new_estimate, static_cast<uint32_t>(1.5 * kAckedBitrate + 10000),
              2000);
  EXPECT_EQ(new_estimate, prev_estimate);
}

TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) {
  // Smoothing experiment disabled
  auto states = CreateAimdRateControlStates();
  states.aimd_rate_control->SetStartBitrate(DataRate::KilobitsPerSec(300));
  EXPECT_EQ(kDefaultPeriodMs,
            states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
  states.simulated_clock->AdvanceTimeMilliseconds(100);
  UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_NE(kDefaultPeriodMs,
            states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}

TEST(AimdRateControlTest, ExpectedPeriodAfter20kbpsDropAnd5kbpsIncrease) {
  auto states = CreateAimdRateControlStates();
  constexpr int kInitialBitrate = 110000;
  SetEstimate(states, kInitialBitrate);
  states.simulated_clock->AdvanceTimeMilliseconds(100);
  // Make the bitrate drop by 20 kbps to get to 90 kbps.
  // The rate increase at 90 kbps should be 5 kbps, so the period should be 4 s.
  constexpr int kAckedBitrate =
      (kInitialBitrate - 20000) / kFractionAfterOveruse;
  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_EQ(5000,
            states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond());
  EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}

TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) {
  auto states = CreateAimdRateControlStates();
  constexpr int kInitialBitrate = 10000;
  SetEstimate(states, kInitialBitrate);
  states.simulated_clock->AdvanceTimeMilliseconds(100);
  // Make a small (1.5 kbps) bitrate drop to 8.5 kbps.
  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kInitialBitrate - 1,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_EQ(kMinBwePeriodMs,
            states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}

TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxNoSmoothingExp) {
  auto states = CreateAimdRateControlStates();
  constexpr int kInitialBitrate = 10010000;
  SetEstimate(states, kInitialBitrate);
  states.simulated_clock->AdvanceTimeMilliseconds(100);
  // Make a large (10 Mbps) bitrate drop to 10 kbps.
  constexpr int kAckedBitrate = 10000 / kFractionAfterOveruse;
  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_EQ(kMaxBwePeriodMs,
            states.aimd_rate_control->GetExpectedBandwidthPeriod().ms());
}

TEST(AimdRateControlTest, SendingRateBoundedWhenThroughputNotEstimated) {
  auto states = CreateAimdRateControlStates();
  constexpr int kInitialBitrateBps = 123000;
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
                    states.simulated_clock->TimeInMilliseconds());
  // AimdRateControl sets the initial bit rate to what it receives after
  // five seconds has passed.
  // TODO(bugs.webrtc.org/9379): The comment in the AimdRateControl does not
  // match the constant.
  constexpr int kInitializationTimeMs = 5000;
  states.simulated_clock->AdvanceTimeMilliseconds(kInitializationTimeMs + 1);
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
                    states.simulated_clock->TimeInMilliseconds());
  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_LE(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps * 1.5 + 10000);
}

TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlr) {
  // When alr is detected, the delay based estimator is not allowed to increase
  // bwe since there will be no feedback from the network if the new estimate
  // is correct.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(true);
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
                    states.simulated_clock->TimeInMilliseconds());
  ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);

  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);
}

TEST(AimdRateControlTest, SetEstimateIncreaseBweInAlr) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(true);
  ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);
  SetEstimate(states, 2 * kInitialBitrateBps);
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            2 * kInitialBitrateBps);
}

TEST(AimdRateControlTest, SetEstimateUpperLimitedByNetworkEstimate) {
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  SetEstimate(states, 500'000);
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper);
}

TEST(AimdRateControlTest, SetEstimateLowerLimitedByNetworkEstimate) {
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(400);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  SetEstimate(states, 100'000);
  // 0.85 is default backoff factor. (`beta_`)
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_lower * 0.85);
}

TEST(AimdRateControlTest,
     SetEstimateIgnoredIfLowerThanNetworkEstimateAndCurrent) {
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  SetEstimate(states, 200'000);
  ASSERT_EQ(states.aimd_rate_control->LatestEstimate().kbps(), 200);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(400);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  // Ignore the next SetEstimate, since the estimate is lower than 85% of
  // the network estimate.
  SetEstimate(states, 100'000);
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate().kbps(), 200);
}

TEST(AimdRateControlTest, SetEstimateIgnoresNetworkEstimatesLowerThanCurrent) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/"
      "ratio:0.85,ignore_acked:true,ignore_decr:true/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  states.aimd_rate_control->SetStartBitrate(DataRate::KilobitsPerSec(30));
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  SetEstimate(states, 500'000);
  ASSERT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper * 0.85);

  NetworkStateEstimate lower_network_estimate;
  lower_network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(300);
  states.aimd_rate_control->SetNetworkStateEstimate(lower_network_estimate);
  SetEstimate(states, 500'000);
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper * 0.85);
}

TEST(AimdRateControlTest, EstimateIncreaseWhileNotInAlr) {
  // Allow the estimate to increase as long as alr is not detected to ensure
  // tha BWE can not get stuck at a certain bitrate.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(false);
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
                    states.simulated_clock->TimeInMilliseconds());
  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_GT(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);
}

TEST(AimdRateControlTest, EstimateNotLimitedByNetworkEstimateIfDisabled) {
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/Disabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(false);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(150);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);

  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_GT(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper);
}

TEST(AimdRateControlTest,
     EstimateSlowlyIncreaseToUpperLinkCapacityEstimateIfConfigured) {
  // Even if alr is detected, the delay based estimator is allowed to increase
  // up to a percentage of upper link capacity.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/"
      "ratio:0.85,ignore_acked:true,immediate_incr:false/"
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(true);

  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  for (int i = 0; i < 10; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
    EXPECT_LT(states.aimd_rate_control->LatestEstimate(),
              network_estimate.link_capacity_upper * 0.85);
  }
  for (int i = 0; i < 50; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper * 0.85);
}

TEST(AimdRateControlTest,
     EstimateImmediatelyIncreaseToUpperLinkCapacityEstimateIfConfigured) {
  // Even if alr is detected, the delay based estimator is allowed to increase
  // up to a percentage of upper link capacity.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/"
      "ratio:0.85,ignore_acked:true,immediate_incr:true/"
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(true);

  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_upper * 0.85);
}

TEST(AimdRateControlTest, EstimateNotLoweredByNetworkEstimate) {
  // The delay based estimator is allowed to increase up to a percentage of
  // upper link capacity but does not decrease unless the delay detector
  // discover an overuse.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/"
      "ratio:0.85,ignore_acked:true,ignore_decr:true/"
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  constexpr int kEstimatedThroughputBps = 30'000;
  SetEstimate(states, kInitialBitrateBps);

  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal,
                      kEstimatedThroughputBps,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  DataRate estimate_after_increase = states.aimd_rate_control->LatestEstimate();
  ASSERT_EQ(estimate_after_increase,
            network_estimate.link_capacity_upper * 0.85);

  // A lower network estimate does not decrease the estimate immediately,
  // but the estimate is not allowed to increase.
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(100);
  network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(80);
  states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
  for (int i = 0; i < 10; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal,
                      kEstimatedThroughputBps,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
    EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
              estimate_after_increase);
  }

  // If the detector detects and overuse, BWE drops to a value relative the
  // network estimate.
  UpdateRateControl(states, BandwidthUsage::kBwOverusing,
                    kEstimatedThroughputBps,
                    states.simulated_clock->TimeInMilliseconds());
  EXPECT_LT(states.aimd_rate_control->LatestEstimate(),
            network_estimate.link_capacity_lower);
  EXPECT_GT(states.aimd_rate_control->LatestEstimate().bps(),
            kEstimatedThroughputBps);
}

TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlrIfNetworkEstimateNotSet) {
  // When alr is detected, the delay based estimator is not allowed to increase
  // bwe since there will be no feedback from the network if the new estimate
  // is correct.
  test::ScopedFieldTrials override_field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/ratio:0.85,ignore_acked:true/"
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  auto states = CreateAimdRateControlStates(/*send_side=*/true);
  constexpr int kInitialBitrateBps = 123000;
  SetEstimate(states, kInitialBitrateBps);
  states.aimd_rate_control->SetInApplicationLimitedRegion(true);
  UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
                    states.simulated_clock->TimeInMilliseconds());
  ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);

  for (int i = 0; i < 100; ++i) {
    UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
                      states.simulated_clock->TimeInMilliseconds());
    states.simulated_clock->AdvanceTimeMilliseconds(100);
  }
  EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
            kInitialBitrateBps);
}

}  // namespace webrtc
