tor-browser

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

rampup_tests.cc (27120B)


      1 /*
      2 *  Copyright (c) 2013 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 "call/rampup_tests.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <string>
     17 #include <utility>
     18 #include <vector>
     19 
     20 #include "absl/flags/flag.h"
     21 #include "absl/strings/str_cat.h"
     22 #include "absl/strings/string_view.h"
     23 #include "api/field_trials_view.h"
     24 #include "api/make_ref_counted.h"
     25 #include "api/rtc_event_log/rtc_event_log.h"
     26 #include "api/rtc_event_log/rtc_event_log_factory.h"
     27 #include "api/rtc_event_log_output_file.h"
     28 #include "api/rtp_parameters.h"
     29 #include "api/sequence_checker.h"
     30 #include "api/task_queue/task_queue_base.h"
     31 #include "api/test/metrics/global_metrics_logger_and_exporter.h"
     32 #include "api/test/metrics/metric.h"
     33 #include "api/test/simulated_network.h"
     34 #include "api/transport/bitrate_settings.h"
     35 #include "api/units/data_rate.h"
     36 #include "api/units/time_delta.h"
     37 #include "api/video/video_codec_type.h"
     38 #include "api/video_codecs/sdp_video_format.h"
     39 #include "call/audio_receive_stream.h"
     40 #include "call/audio_send_stream.h"
     41 #include "call/call.h"
     42 #include "call/fake_network_pipe.h"
     43 #include "call/flexfec_receive_stream.h"
     44 #include "call/video_receive_stream.h"
     45 #include "call/video_send_stream.h"
     46 #include "rtc_base/checks.h"
     47 #include "rtc_base/task_queue_for_test.h"
     48 #include "rtc_base/task_utils/repeating_task.h"
     49 #include "test/call_test.h"
     50 #include "test/encoder_settings.h"
     51 #include "test/gtest.h"
     52 #include "test/rtp_rtcp_observer.h"
     53 #include "test/video_test_constants.h"
     54 #include "video/config/video_encoder_config.h"
     55 
     56 ABSL_FLAG(std::string,
     57          ramp_dump_name,
     58          "",
     59          "Filename for dumped received RTP stream.");
     60 
     61 namespace webrtc {
     62 namespace {
     63 
     64 using test::GetGlobalMetricsLogger;
     65 using test::ImprovementDirection;
     66 using test::Unit;
     67 
     68 constexpr TimeDelta kPollInterval = TimeDelta::Millis(20);
     69 const int kExpectedHighVideoBitrateBps = 80000;
     70 const int kExpectedHighAudioBitrateBps = 30000;
     71 const int kLowBandwidthLimitBps = 20000;
     72 // Set target detected bitrate to slightly larger than the target bitrate to
     73 // avoid flakiness.
     74 const int kLowBitrateMarginBps = 2000;
     75 
     76 std::vector<uint32_t> GenerateSsrcs(size_t num_streams, uint32_t ssrc_offset) {
     77  std::vector<uint32_t> ssrcs;
     78  for (size_t i = 0; i != num_streams; ++i)
     79    ssrcs.push_back(static_cast<uint32_t>(ssrc_offset + i));
     80  return ssrcs;
     81 }
     82 
     83 }  // namespace
     84 
     85 RampUpTester::RampUpTester(size_t num_video_streams,
     86                           size_t num_audio_streams,
     87                           size_t num_flexfec_streams,
     88                           unsigned int start_bitrate_bps,
     89                           int64_t min_run_time_ms,
     90                           bool rtx,
     91                           bool red,
     92                           bool report_perf_stats,
     93                           TaskQueueBase* task_queue)
     94    : EndToEndTest(test::VideoTestConstants::kLongTimeout),
     95      clock_(Clock::GetRealTimeClock()),
     96      num_video_streams_(num_video_streams),
     97      num_audio_streams_(num_audio_streams),
     98      num_flexfec_streams_(num_flexfec_streams),
     99      rtx_(rtx),
    100      red_(red),
    101      report_perf_stats_(report_perf_stats),
    102      sender_call_(nullptr),
    103      send_stream_(nullptr),
    104      send_transport_(nullptr),
    105      send_simulated_network_(nullptr),
    106      start_bitrate_bps_(start_bitrate_bps),
    107      min_run_time_ms_(min_run_time_ms),
    108      expected_bitrate_bps_(0),
    109      test_start_ms_(-1),
    110      ramp_up_finished_ms_(-1),
    111      video_ssrcs_(GenerateSsrcs(num_video_streams_, 100)),
    112      video_rtx_ssrcs_(GenerateSsrcs(num_video_streams_, 200)),
    113      audio_ssrcs_(GenerateSsrcs(num_audio_streams_, 300)),
    114      task_queue_(task_queue) {
    115  if (red_)
    116    EXPECT_EQ(0u, num_flexfec_streams_);
    117  EXPECT_LE(num_audio_streams_, 1u);
    118 }
    119 
    120 RampUpTester::~RampUpTester() = default;
    121 
    122 void RampUpTester::ModifySenderBitrateConfig(
    123    BitrateConstraints* bitrate_config) {
    124  if (start_bitrate_bps_ != 0) {
    125    bitrate_config->start_bitrate_bps = start_bitrate_bps_;
    126  }
    127  bitrate_config->min_bitrate_bps = 10000;
    128 }
    129 
    130 void RampUpTester::OnVideoStreamsCreated(
    131    VideoSendStream* send_stream,
    132    const std::vector<VideoReceiveStreamInterface*>& /* receive_streams */) {
    133  send_stream_ = send_stream;
    134 }
    135 
    136 BuiltInNetworkBehaviorConfig RampUpTester::GetSendTransportConfig() const {
    137  return forward_transport_config_;
    138 }
    139 
    140 size_t RampUpTester::GetNumVideoStreams() const {
    141  return num_video_streams_;
    142 }
    143 
    144 size_t RampUpTester::GetNumAudioStreams() const {
    145  return num_audio_streams_;
    146 }
    147 
    148 size_t RampUpTester::GetNumFlexfecStreams() const {
    149  return num_flexfec_streams_;
    150 }
    151 
    152 class RampUpTester::VideoStreamFactory
    153    : public VideoEncoderConfig::VideoStreamFactoryInterface {
    154 public:
    155  VideoStreamFactory() {}
    156 
    157 private:
    158  std::vector<VideoStream> CreateEncoderStreams(
    159      const FieldTrialsView& /*field_trials*/,
    160      int frame_width,
    161      int frame_height,
    162      const VideoEncoderConfig& encoder_config) override {
    163    std::vector<VideoStream> streams =
    164        test::CreateVideoStreams(frame_width, frame_height, encoder_config);
    165    if (encoder_config.number_of_streams == 1) {
    166      streams[0].target_bitrate_bps = streams[0].max_bitrate_bps = 2000000;
    167    }
    168    return streams;
    169  }
    170 };
    171 
    172 void RampUpTester::ModifyVideoConfigs(
    173    VideoSendStream::Config* send_config,
    174    std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
    175    VideoEncoderConfig* encoder_config) {
    176  send_config->suspend_below_min_bitrate = true;
    177  encoder_config->number_of_streams = num_video_streams_;
    178  encoder_config->max_bitrate_bps = 2000000;
    179  encoder_config->video_stream_factory =
    180      make_ref_counted<RampUpTester::VideoStreamFactory>();
    181  if (num_video_streams_ == 1) {
    182    // For single stream rampup until 1mbps
    183    expected_bitrate_bps_ = kSingleStreamTargetBps;
    184  } else {
    185    // To ensure simulcast rate allocation.
    186    send_config->rtp.payload_name = "VP8";
    187    encoder_config->codec_type = kVideoCodecVP8;
    188    std::vector<VideoStream> streams = test::CreateVideoStreams(
    189        test::VideoTestConstants::kDefaultWidth,
    190        test::VideoTestConstants::kDefaultHeight, *encoder_config);
    191    // For multi stream rampup until all streams are being sent. That means
    192    // enough bitrate to send all the target streams plus the min bitrate of
    193    // the last one.
    194    expected_bitrate_bps_ = streams.back().min_bitrate_bps;
    195    for (size_t i = 0; i < streams.size() - 1; ++i) {
    196      expected_bitrate_bps_ += streams[i].target_bitrate_bps;
    197    }
    198  }
    199 
    200  send_config->rtp.nack.rtp_history_ms =
    201      test::VideoTestConstants::kNackRtpHistoryMs;
    202  send_config->rtp.ssrcs = video_ssrcs_;
    203  if (rtx_) {
    204    send_config->rtp.rtx.payload_type =
    205        test::VideoTestConstants::kSendRtxPayloadType;
    206    send_config->rtp.rtx.ssrcs = video_rtx_ssrcs_;
    207  }
    208  if (red_) {
    209    send_config->rtp.ulpfec.ulpfec_payload_type =
    210        test::VideoTestConstants::kUlpfecPayloadType;
    211    send_config->rtp.ulpfec.red_payload_type =
    212        test::VideoTestConstants::kRedPayloadType;
    213    if (rtx_) {
    214      send_config->rtp.ulpfec.red_rtx_payload_type =
    215          test::VideoTestConstants::kRtxRedPayloadType;
    216    }
    217  }
    218 
    219  size_t i = 0;
    220  for (VideoReceiveStreamInterface::Config& recv_config : *receive_configs) {
    221    recv_config.decoders.reserve(1);
    222    recv_config.decoders[0].payload_type = send_config->rtp.payload_type;
    223    recv_config.decoders[0].video_format =
    224        SdpVideoFormat(send_config->rtp.payload_name);
    225 
    226    recv_config.rtp.remote_ssrc = video_ssrcs_[i];
    227    recv_config.rtp.nack.rtp_history_ms = send_config->rtp.nack.rtp_history_ms;
    228 
    229    if (red_) {
    230      recv_config.rtp.red_payload_type =
    231          send_config->rtp.ulpfec.red_payload_type;
    232      recv_config.rtp.ulpfec_payload_type =
    233          send_config->rtp.ulpfec.ulpfec_payload_type;
    234      if (rtx_) {
    235        recv_config.rtp.rtx_associated_payload_types
    236            [send_config->rtp.ulpfec.red_rtx_payload_type] =
    237            send_config->rtp.ulpfec.red_payload_type;
    238      }
    239    }
    240 
    241    if (rtx_) {
    242      recv_config.rtp.rtx_ssrc = video_rtx_ssrcs_[i];
    243      recv_config.rtp
    244          .rtx_associated_payload_types[send_config->rtp.rtx.payload_type] =
    245          send_config->rtp.payload_type;
    246    }
    247    ++i;
    248  }
    249 
    250  RTC_DCHECK_LE(num_flexfec_streams_, 1);
    251  if (num_flexfec_streams_ == 1) {
    252    send_config->rtp.flexfec.payload_type =
    253        test::VideoTestConstants::kFlexfecPayloadType;
    254    send_config->rtp.flexfec.ssrc = test::VideoTestConstants::kFlexfecSendSsrc;
    255    send_config->rtp.flexfec.protected_media_ssrcs = {video_ssrcs_[0]};
    256  }
    257 }
    258 
    259 void RampUpTester::ModifyAudioConfigs(
    260    AudioSendStream::Config* send_config,
    261    std::vector<AudioReceiveStreamInterface::Config>* receive_configs) {
    262  if (num_audio_streams_ == 0)
    263    return;
    264 
    265  send_config->rtp.ssrc = audio_ssrcs_[0];
    266  send_config->min_bitrate_bps = 6000;
    267  send_config->max_bitrate_bps = 60000;
    268 
    269  for (AudioReceiveStreamInterface::Config& recv_config : *receive_configs) {
    270    recv_config.rtp.remote_ssrc = send_config->rtp.ssrc;
    271  }
    272 }
    273 
    274 void RampUpTester::ModifyFlexfecConfigs(
    275    std::vector<FlexfecReceiveStream::Config>* receive_configs) {
    276  if (num_flexfec_streams_ == 0)
    277    return;
    278  RTC_DCHECK_EQ(1, num_flexfec_streams_);
    279  (*receive_configs)[0].payload_type =
    280      test::VideoTestConstants::kFlexfecPayloadType;
    281  (*receive_configs)[0].rtp.remote_ssrc =
    282      test::VideoTestConstants::kFlexfecSendSsrc;
    283  (*receive_configs)[0].protected_media_ssrcs = {video_ssrcs_[0]};
    284  (*receive_configs)[0].rtp.local_ssrc = video_ssrcs_[0];
    285 }
    286 
    287 void RampUpTester::OnCallsCreated(Call* sender_call,
    288                                  Call* /* receiver_call */) {
    289  RTC_DCHECK(sender_call);
    290  sender_call_ = sender_call;
    291  pending_task_ = RepeatingTaskHandle::Start(task_queue_, [this] {
    292    PollStats();
    293    return kPollInterval;
    294  });
    295 }
    296 
    297 void RampUpTester::OnTransportCreated(
    298    test::PacketTransport* to_receiver,
    299    SimulatedNetworkInterface* sender_network,
    300    test::PacketTransport* /* to_sender */,
    301    SimulatedNetworkInterface* /* receiver_network */) {
    302  RTC_DCHECK_RUN_ON(task_queue_);
    303 
    304  send_transport_ = to_receiver;
    305  send_simulated_network_ = sender_network;
    306 }
    307 
    308 void RampUpTester::PollStats() {
    309  RTC_DCHECK_RUN_ON(task_queue_);
    310 
    311  Call::Stats stats = sender_call_->GetStats();
    312  EXPECT_GE(expected_bitrate_bps_, 0);
    313 
    314  if (stats.send_bandwidth_bps >= expected_bitrate_bps_ &&
    315      (min_run_time_ms_ == -1 ||
    316       clock_->TimeInMilliseconds() - test_start_ms_ >= min_run_time_ms_)) {
    317    ramp_up_finished_ms_ = clock_->TimeInMilliseconds();
    318    observation_complete_.Set();
    319    pending_task_.Stop();
    320  }
    321 }
    322 
    323 void RampUpTester::ReportResult(
    324    absl::string_view measurement,
    325    size_t value,
    326    Unit unit,
    327    ImprovementDirection improvement_direction) const {
    328  GetGlobalMetricsLogger()->LogSingleValueMetric(
    329      measurement,
    330      ::testing::UnitTest::GetInstance()->current_test_info()->name(), value,
    331      unit, improvement_direction);
    332 }
    333 
    334 void RampUpTester::AccumulateStats(const VideoSendStream::StreamStats& stream,
    335                                   size_t* total_packets_sent,
    336                                   size_t* total_sent,
    337                                   size_t* padding_sent,
    338                                   size_t* media_sent) const {
    339  *total_packets_sent += stream.rtp_stats.transmitted.packets +
    340                         stream.rtp_stats.retransmitted.packets +
    341                         stream.rtp_stats.fec.packets;
    342  *total_sent += stream.rtp_stats.transmitted.TotalBytes() +
    343                 stream.rtp_stats.retransmitted.TotalBytes() +
    344                 stream.rtp_stats.fec.TotalBytes();
    345  *padding_sent += stream.rtp_stats.transmitted.padding_bytes +
    346                   stream.rtp_stats.retransmitted.padding_bytes +
    347                   stream.rtp_stats.fec.padding_bytes;
    348  *media_sent += stream.rtp_stats.MediaPayloadBytes();
    349 }
    350 
    351 void RampUpTester::TriggerTestDone() {
    352  RTC_DCHECK_GE(test_start_ms_, 0);
    353 
    354  // Stop polling stats.
    355  // Corner case for webrtc_quick_perf_test
    356  SendTask(task_queue_, [this] { pending_task_.Stop(); });
    357 
    358  // TODO(holmer): Add audio send stats here too when those APIs are available.
    359  if (!send_stream_)
    360    return;
    361 
    362  VideoSendStream::Stats send_stats;
    363  SendTask(task_queue_, [&] { send_stats = send_stream_->GetStats(); });
    364 
    365  send_stream_ = nullptr;  // To avoid dereferencing a bad pointer.
    366 
    367  size_t total_packets_sent = 0;
    368  size_t total_sent = 0;
    369  size_t padding_sent = 0;
    370  size_t media_sent = 0;
    371  for (uint32_t ssrc : video_ssrcs_) {
    372    AccumulateStats(send_stats.substreams[ssrc], &total_packets_sent,
    373                    &total_sent, &padding_sent, &media_sent);
    374  }
    375 
    376  size_t rtx_total_packets_sent = 0;
    377  size_t rtx_total_sent = 0;
    378  size_t rtx_padding_sent = 0;
    379  size_t rtx_media_sent = 0;
    380  for (uint32_t rtx_ssrc : video_rtx_ssrcs_) {
    381    AccumulateStats(send_stats.substreams[rtx_ssrc], &rtx_total_packets_sent,
    382                    &rtx_total_sent, &rtx_padding_sent, &rtx_media_sent);
    383  }
    384 
    385  if (report_perf_stats_) {
    386    ReportResult("ramp-up-media-sent", media_sent, Unit::kBytes,
    387                 ImprovementDirection::kBiggerIsBetter);
    388    ReportResult("ramp-up-padding-sent", padding_sent, Unit::kBytes,
    389                 ImprovementDirection::kSmallerIsBetter);
    390    ReportResult("ramp-up-rtx-media-sent", rtx_media_sent, Unit::kBytes,
    391                 ImprovementDirection::kBiggerIsBetter);
    392    ReportResult("ramp-up-rtx-padding-sent", rtx_padding_sent, Unit::kBytes,
    393                 ImprovementDirection::kSmallerIsBetter);
    394    if (ramp_up_finished_ms_ >= 0) {
    395      ReportResult("ramp-up-time", ramp_up_finished_ms_ - test_start_ms_,
    396                   Unit::kMilliseconds, ImprovementDirection::kSmallerIsBetter);
    397    }
    398    ReportResult("ramp-up-average-network-latency",
    399                 send_transport_->GetAverageDelayMs(), Unit::kMilliseconds,
    400                 ImprovementDirection::kSmallerIsBetter);
    401  }
    402 }
    403 
    404 void RampUpTester::PerformTest() {
    405  test_start_ms_ = clock_->TimeInMilliseconds();
    406  EXPECT_TRUE(Wait()) << "Timed out while waiting for ramp-up to complete.";
    407  TriggerTestDone();
    408 }
    409 
    410 RampUpDownUpTester::RampUpDownUpTester(size_t num_video_streams,
    411                                       size_t num_audio_streams,
    412                                       size_t num_flexfec_streams,
    413                                       unsigned int start_bitrate_bps,
    414                                       bool rtx,
    415                                       bool red,
    416                                       const std::vector<int>& loss_rates,
    417                                       bool report_perf_stats,
    418                                       TaskQueueBase* task_queue)
    419    : RampUpTester(num_video_streams,
    420                   num_audio_streams,
    421                   num_flexfec_streams,
    422                   start_bitrate_bps,
    423                   0,
    424                   rtx,
    425                   red,
    426                   report_perf_stats,
    427                   task_queue),
    428      link_rates_({4 * GetExpectedHighBitrate() / (3 * 1000),
    429                   kLowBandwidthLimitBps / 1000,
    430                   4 * GetExpectedHighBitrate() / (3 * 1000), 0}),
    431      test_state_(kFirstRampup),
    432      next_state_(kTransitionToNextState),
    433      state_start_ms_(clock_->TimeInMilliseconds()),
    434      interval_start_ms_(clock_->TimeInMilliseconds()),
    435      sent_bytes_(0),
    436      loss_rates_(loss_rates) {
    437  forward_transport_config_.link_capacity =
    438      DataRate::KilobitsPerSec(link_rates_[test_state_]);
    439  forward_transport_config_.queue_delay_ms = 100;
    440  forward_transport_config_.loss_percent = loss_rates_[test_state_];
    441 }
    442 
    443 RampUpDownUpTester::~RampUpDownUpTester() {}
    444 
    445 void RampUpDownUpTester::PollStats() {
    446  if (test_state_ == kTestEnd) {
    447    pending_task_.Stop();
    448  }
    449 
    450  int transmit_bitrate_bps = 0;
    451  bool suspended = false;
    452  if (num_video_streams_ > 0 && send_stream_) {
    453    VideoSendStream::Stats stats = send_stream_->GetStats();
    454    for (const auto& it : stats.substreams) {
    455      transmit_bitrate_bps += it.second.total_bitrate_bps;
    456    }
    457    suspended = stats.suspended;
    458  }
    459  if (num_audio_streams_ > 0 && sender_call_) {
    460    // An audio send stream doesn't have bitrate stats, so the call send BW is
    461    // currently used instead.
    462    transmit_bitrate_bps = sender_call_->GetStats().send_bandwidth_bps;
    463  }
    464 
    465  EvolveTestState(transmit_bitrate_bps, suspended);
    466 }
    467 
    468 void RampUpDownUpTester::ModifyReceiverBitrateConfig(
    469    BitrateConstraints* bitrate_config) {
    470  bitrate_config->min_bitrate_bps = 10000;
    471 }
    472 
    473 std::string RampUpDownUpTester::GetModifierString() const {
    474  std::string str("_");
    475  if (num_video_streams_ > 0) {
    476    str += absl::StrCat(num_video_streams_);
    477    str += "stream";
    478    str += (num_video_streams_ > 1 ? "s" : "");
    479    str += "_";
    480  }
    481  if (num_audio_streams_ > 0) {
    482    str += absl::StrCat(num_audio_streams_);
    483    str += "stream";
    484    str += (num_audio_streams_ > 1 ? "s" : "");
    485    str += "_";
    486  }
    487  str += (rtx_ ? "" : "no");
    488  str += "rtx_";
    489  str += (red_ ? "" : "no");
    490  str += "red";
    491  return str;
    492 }
    493 
    494 int RampUpDownUpTester::GetExpectedHighBitrate() const {
    495  int expected_bitrate_bps = 0;
    496  if (num_audio_streams_ > 0)
    497    expected_bitrate_bps += kExpectedHighAudioBitrateBps;
    498  if (num_video_streams_ > 0)
    499    expected_bitrate_bps += kExpectedHighVideoBitrateBps;
    500  return expected_bitrate_bps;
    501 }
    502 
    503 size_t RampUpDownUpTester::GetFecBytes() const {
    504  size_t flex_fec_bytes = 0;
    505  if (num_flexfec_streams_ > 0) {
    506    VideoSendStream::Stats stats = send_stream_->GetStats();
    507    for (const auto& kv : stats.substreams)
    508      flex_fec_bytes += kv.second.rtp_stats.fec.TotalBytes();
    509  }
    510  return flex_fec_bytes;
    511 }
    512 
    513 bool RampUpDownUpTester::ExpectingFec() const {
    514  return num_flexfec_streams_ > 0 && forward_transport_config_.loss_percent > 0;
    515 }
    516 
    517 void RampUpDownUpTester::EvolveTestState(int bitrate_bps, bool suspended) {
    518  int64_t now = clock_->TimeInMilliseconds();
    519  switch (test_state_) {
    520    case kFirstRampup:
    521      EXPECT_FALSE(suspended);
    522      if (bitrate_bps >= GetExpectedHighBitrate()) {
    523        if (report_perf_stats_) {
    524          GetGlobalMetricsLogger()->LogSingleValueMetric(
    525              "ramp_up_down_up" + GetModifierString(), "first_rampup",
    526              now - state_start_ms_, Unit::kMilliseconds,
    527              ImprovementDirection::kSmallerIsBetter);
    528        }
    529        // Apply loss during the transition between states if FEC is enabled.
    530        forward_transport_config_.loss_percent = loss_rates_[test_state_];
    531        test_state_ = kTransitionToNextState;
    532        next_state_ = kLowRate;
    533      }
    534      break;
    535    case kLowRate: {
    536      // Audio streams are never suspended.
    537      bool check_suspend_state = num_video_streams_ > 0;
    538      if (bitrate_bps < kLowBandwidthLimitBps + kLowBitrateMarginBps &&
    539          suspended == check_suspend_state) {
    540        if (report_perf_stats_) {
    541          GetGlobalMetricsLogger()->LogSingleValueMetric(
    542              "ramp_up_down_up" + GetModifierString(), "rampdown",
    543              now - state_start_ms_, Unit::kMilliseconds,
    544              ImprovementDirection::kSmallerIsBetter);
    545        }
    546        // Apply loss during the transition between states if FEC is enabled.
    547        forward_transport_config_.loss_percent = loss_rates_[test_state_];
    548        test_state_ = kTransitionToNextState;
    549        next_state_ = kSecondRampup;
    550      }
    551      break;
    552    }
    553    case kSecondRampup:
    554      if (bitrate_bps >= GetExpectedHighBitrate() && !suspended) {
    555        if (report_perf_stats_) {
    556          GetGlobalMetricsLogger()->LogSingleValueMetric(
    557              "ramp_up_down_up" + GetModifierString(), "second_rampup",
    558              now - state_start_ms_, Unit::kMilliseconds,
    559              ImprovementDirection::kSmallerIsBetter);
    560          ReportResult("ramp-up-down-up-average-network-latency",
    561                       send_transport_->GetAverageDelayMs(),
    562                       Unit::kMilliseconds,
    563                       ImprovementDirection::kSmallerIsBetter);
    564        }
    565        // Apply loss during the transition between states if FEC is enabled.
    566        forward_transport_config_.loss_percent = loss_rates_[test_state_];
    567        test_state_ = kTransitionToNextState;
    568        next_state_ = kTestEnd;
    569      }
    570      break;
    571    case kTestEnd:
    572      observation_complete_.Set();
    573      break;
    574    case kTransitionToNextState:
    575      if (!ExpectingFec() || GetFecBytes() > 0) {
    576        test_state_ = next_state_;
    577        forward_transport_config_.link_capacity =
    578            DataRate::KilobitsPerSec(link_rates_[test_state_]);
    579        // No loss while ramping up and down as it may affect the BWE
    580        // negatively, making the test flaky.
    581        forward_transport_config_.loss_percent = 0;
    582        state_start_ms_ = now;
    583        interval_start_ms_ = now;
    584        sent_bytes_ = 0;
    585        send_simulated_network_->SetConfig(forward_transport_config_);
    586      }
    587      break;
    588  }
    589 }
    590 
    591 class RampUpTest : public test::CallTest {
    592 public:
    593  RampUpTest() {
    594    std::string dump_name(absl::GetFlag(FLAGS_ramp_dump_name));
    595    if (!dump_name.empty()) {
    596      std::unique_ptr<RtcEventLog> send_event_log =
    597          rtc_event_log_factory_.Create(env());
    598      std::unique_ptr<RtcEventLog> recv_event_log =
    599          rtc_event_log_factory_.Create(env());
    600      bool event_log_started =
    601          send_event_log->StartLogging(
    602              std::make_unique<RtcEventLogOutputFile>(
    603                  dump_name + ".send.rtc.dat", RtcEventLog::kUnlimitedOutput),
    604              RtcEventLog::kImmediateOutput) &&
    605          recv_event_log->StartLogging(
    606              std::make_unique<RtcEventLogOutputFile>(
    607                  dump_name + ".recv.rtc.dat", RtcEventLog::kUnlimitedOutput),
    608              RtcEventLog::kImmediateOutput);
    609      RTC_DCHECK(event_log_started);
    610      SetSendEventLog(std::move(send_event_log));
    611      SetRecvEventLog(std::move(recv_event_log));
    612    }
    613  }
    614 
    615 private:
    616  RtcEventLogFactory rtc_event_log_factory_;
    617 };
    618 
    619 static const uint32_t kStartBitrateBps = 60000;
    620 
    621 TEST_F(RampUpTest, UpDownUpAbsSendTimeSimulcastRedRtx) {
    622  std::vector<int> loss_rates = {0, 0, 0, 0};
    623  RegisterRtpExtension(
    624      RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
    625  RampUpDownUpTester test(3, 0, 0, kStartBitrateBps, true, true, loss_rates,
    626                          true, task_queue());
    627  RunBaseTest(&test);
    628 }
    629 
    630 // TODO(bugs.webrtc.org/8878)
    631 #if defined(WEBRTC_MAC)
    632 #define MAYBE_UpDownUpTransportSequenceNumberRtx \
    633  DISABLED_UpDownUpTransportSequenceNumberRtx
    634 #else
    635 #define MAYBE_UpDownUpTransportSequenceNumberRtx \
    636  UpDownUpTransportSequenceNumberRtx
    637 #endif
    638 TEST_F(RampUpTest, MAYBE_UpDownUpTransportSequenceNumberRtx) {
    639  std::vector<int> loss_rates = {0, 0, 0, 0};
    640  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    641                                    kTransportSequenceNumberExtensionId));
    642  RampUpDownUpTester test(3, 0, 0, kStartBitrateBps, true, false, loss_rates,
    643                          true, task_queue());
    644  RunBaseTest(&test);
    645 }
    646 
    647 // TODO(holmer): Tests which don't report perf stats should be moved to a
    648 // different executable since they per definition are not perf tests.
    649 // This test is disabled because it crashes on Linux, and is flaky on other
    650 // platforms. See: crbug.com/webrtc/7919
    651 TEST_F(RampUpTest, DISABLED_UpDownUpTransportSequenceNumberPacketLoss) {
    652  std::vector<int> loss_rates = {20, 0, 0, 0};
    653  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    654                                    kTransportSequenceNumberExtensionId));
    655  RampUpDownUpTester test(1, 0, 1, kStartBitrateBps, true, false, loss_rates,
    656                          false, task_queue());
    657  RunBaseTest(&test);
    658 }
    659 
    660 // TODO(bugs.webrtc.org/8878)
    661 #if defined(WEBRTC_MAC)
    662 #define MAYBE_UpDownUpAudioVideoTransportSequenceNumberRtx \
    663  DISABLED_UpDownUpAudioVideoTransportSequenceNumberRtx
    664 #else
    665 #define MAYBE_UpDownUpAudioVideoTransportSequenceNumberRtx \
    666  UpDownUpAudioVideoTransportSequenceNumberRtx
    667 #endif
    668 TEST_F(RampUpTest, MAYBE_UpDownUpAudioVideoTransportSequenceNumberRtx) {
    669  std::vector<int> loss_rates = {0, 0, 0, 0};
    670  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    671                                    kTransportSequenceNumberExtensionId));
    672  RampUpDownUpTester test(3, 1, 0, kStartBitrateBps, true, false, loss_rates,
    673                          false, task_queue());
    674  RunBaseTest(&test);
    675 }
    676 
    677 TEST_F(RampUpTest, UpDownUpAudioTransportSequenceNumberRtx) {
    678  std::vector<int> loss_rates = {0, 0, 0, 0};
    679  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    680                                    kTransportSequenceNumberExtensionId));
    681  RampUpDownUpTester test(0, 1, 0, kStartBitrateBps, true, false, loss_rates,
    682                          false, task_queue());
    683  RunBaseTest(&test);
    684 }
    685 
    686 TEST_F(RampUpTest, TOffsetSimulcastRedRtx) {
    687  RegisterRtpExtension(RtpExtension(RtpExtension::kTimestampOffsetUri,
    688                                    kTransmissionTimeOffsetExtensionId));
    689  RampUpTester test(3, 0, 0, 0, 0, true, true, true, task_queue());
    690  RunBaseTest(&test);
    691 }
    692 
    693 TEST_F(RampUpTest, AbsSendTime) {
    694  RegisterRtpExtension(
    695      RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
    696  RampUpTester test(1, 0, 0, 0, 0, false, false, false, task_queue());
    697  RunBaseTest(&test);
    698 }
    699 
    700 TEST_F(RampUpTest, AbsSendTimeSimulcastRedRtx) {
    701  RegisterRtpExtension(
    702      RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeExtensionId));
    703  RampUpTester test(3, 0, 0, 0, 0, true, true, true, task_queue());
    704  RunBaseTest(&test);
    705 }
    706 
    707 TEST_F(RampUpTest, TransportSequenceNumber) {
    708  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    709                                    kTransportSequenceNumberExtensionId));
    710  RampUpTester test(1, 0, 0, 0, 0, false, false, false, task_queue());
    711  RunBaseTest(&test);
    712 }
    713 
    714 TEST_F(RampUpTest, TransportSequenceNumberSimulcast) {
    715  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    716                                    kTransportSequenceNumberExtensionId));
    717  RampUpTester test(3, 0, 0, 0, 0, false, false, false, task_queue());
    718  RunBaseTest(&test);
    719 }
    720 
    721 TEST_F(RampUpTest, TransportSequenceNumberSimulcastRedRtx) {
    722  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    723                                    kTransportSequenceNumberExtensionId));
    724  RampUpTester test(3, 0, 0, 0, 0, true, true, true, task_queue());
    725  RunBaseTest(&test);
    726 }
    727 
    728 TEST_F(RampUpTest, AudioTransportSequenceNumber) {
    729  RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
    730                                    kTransportSequenceNumberExtensionId));
    731  RampUpTester test(0, 1, 0, 300000, 10000, false, false, false, task_queue());
    732  RunBaseTest(&test);
    733 }
    734 
    735 }  // namespace webrtc