tor-browser

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

nack_requester_unittest.cc (9929B)


      1 /*
      2 *  Copyright (c) 2016 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/video_coding/nack_requester.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <memory>
     17 #include <vector>
     18 
     19 #include "api/task_queue/task_queue_base.h"
     20 #include "api/units/time_delta.h"
     21 #include "modules/include/module_common_types.h"
     22 #include "rtc_base/checks.h"
     23 #include "rtc_base/thread.h"
     24 #include "system_wrappers/include/clock.h"
     25 #include "test/create_test_field_trials.h"
     26 #include "test/gtest.h"
     27 #include "test/run_loop.h"
     28 
     29 namespace webrtc {
     30 // TODO(bugs.webrtc.org/11594): Use the use the GlobalSimulatedTimeController
     31 // instead of RunLoop. At the moment we mix use of the Clock and the underlying
     32 // implementation of RunLoop, which is realtime.
     33 class TestNackRequester : public ::testing::Test,
     34                          public NackSender,
     35                          public KeyFrameRequestSender {
     36 protected:
     37  TestNackRequester()
     38      : clock_(new SimulatedClock(0)), keyframes_requested_(0) {}
     39 
     40  void SetUp() override {}
     41 
     42  void SendNack(const std::vector<uint16_t>& sequence_numbers,
     43                bool /* buffering_allowed */) override {
     44    sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
     45                       sequence_numbers.end());
     46    if (waiting_for_send_nack_) {
     47      waiting_for_send_nack_ = false;
     48      loop_.Quit();
     49    }
     50  }
     51 
     52  void RequestKeyFrame() override { ++keyframes_requested_; }
     53 
     54  void Flush() {
     55    // nack_module.Process();
     56    loop_.Flush();
     57  }
     58 
     59  bool WaitForSendNack() {
     60    if (timed_out_) {
     61      RTC_DCHECK_NOTREACHED();
     62      return false;
     63    }
     64 
     65    RTC_DCHECK(!waiting_for_send_nack_);
     66 
     67    waiting_for_send_nack_ = true;
     68    loop_.task_queue()->PostDelayedTask(
     69        [this]() {
     70          timed_out_ = true;
     71          loop_.Quit();
     72        },
     73        TimeDelta::Seconds(1));
     74 
     75    loop_.Run();
     76 
     77    if (timed_out_)
     78      return false;
     79 
     80    RTC_DCHECK(!waiting_for_send_nack_);
     81    return true;
     82  }
     83 
     84  NackRequester& CreateNackModule(
     85      TimeDelta interval = NackPeriodicProcessor::kUpdateInterval) {
     86    RTC_DCHECK(!nack_module_.get());
     87    nack_periodic_processor_ =
     88        std::make_unique<NackPeriodicProcessor>(interval);
     89    nack_module_ = std::make_unique<NackRequester>(
     90        TaskQueueBase::Current(), nack_periodic_processor_.get(), clock_.get(),
     91        this, this, CreateTestFieldTrials());
     92    nack_module_->UpdateRtt(kDefaultRttMs);
     93    return *nack_module_;
     94  }
     95 
     96  static constexpr int64_t kDefaultRttMs = 20;
     97  AutoThread main_thread_;
     98  test::RunLoop loop_;
     99  std::unique_ptr<SimulatedClock> clock_;
    100  std::unique_ptr<NackPeriodicProcessor> nack_periodic_processor_;
    101  std::unique_ptr<NackRequester> nack_module_;
    102  std::vector<uint16_t> sent_nacks_;
    103  int keyframes_requested_;
    104  bool waiting_for_send_nack_ = false;
    105  bool timed_out_ = false;
    106 };
    107 
    108 TEST_F(TestNackRequester, NackOnePacket) {
    109  NackRequester& nack_module = CreateNackModule();
    110  nack_module.OnReceivedPacket(1);
    111  nack_module.OnReceivedPacket(3);
    112  ASSERT_EQ(1u, sent_nacks_.size());
    113  EXPECT_EQ(2, sent_nacks_[0]);
    114 }
    115 
    116 TEST_F(TestNackRequester, WrappingSeqNum) {
    117  NackRequester& nack_module = CreateNackModule();
    118  nack_module.OnReceivedPacket(0xfffe);
    119  nack_module.OnReceivedPacket(1);
    120  ASSERT_EQ(2u, sent_nacks_.size());
    121  EXPECT_EQ(0xffff, sent_nacks_[0]);
    122  EXPECT_EQ(0, sent_nacks_[1]);
    123 }
    124 
    125 TEST_F(TestNackRequester, ResendNack) {
    126  NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
    127  nack_module.OnReceivedPacket(1);
    128  nack_module.OnReceivedPacket(3);
    129  size_t expected_nacks_sent = 1;
    130  ASSERT_EQ(expected_nacks_sent, sent_nacks_.size());
    131  EXPECT_EQ(2, sent_nacks_[0]);
    132 
    133  nack_module.UpdateRtt(1);
    134  clock_->AdvanceTimeMilliseconds(1);
    135  WaitForSendNack();  // Fast retransmit allowed.
    136  EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
    137 
    138  // Each try has to wait rtt by default.
    139  for (int i = 2; i < 10; ++i) {
    140    // Change RTT, above the 40ms max for exponential backoff.
    141    TimeDelta rtt = TimeDelta::Millis(160);  // + (i * 10 - 40)
    142    nack_module.UpdateRtt(rtt.ms());
    143 
    144    // RTT gets capped at 160ms in backoff calculations.
    145    TimeDelta expected_backoff_delay =
    146        (i - 1) * std::min(rtt, TimeDelta::Millis(160));
    147 
    148    // Move to one millisecond before next allowed NACK.
    149    clock_->AdvanceTimeMilliseconds(expected_backoff_delay.ms() - 1);
    150    Flush();
    151    EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
    152 
    153    // Move to one millisecond after next allowed NACK.
    154    // After rather than on to avoid rounding errors.
    155    clock_->AdvanceTimeMilliseconds(2);
    156    WaitForSendNack();  // Now allowed.
    157    EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
    158  }
    159 
    160  // Giving up after 10 tries.
    161  clock_->AdvanceTimeMilliseconds(3000);
    162  Flush();
    163  EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
    164 }
    165 
    166 TEST_F(TestNackRequester, ResendPacketMaxRetries) {
    167  NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
    168  nack_module.OnReceivedPacket(1);
    169  nack_module.OnReceivedPacket(3);
    170  ASSERT_EQ(1u, sent_nacks_.size());
    171  EXPECT_EQ(2, sent_nacks_[0]);
    172 
    173  int backoff_factor = 1;
    174  for (size_t retries = 1; retries < 10; ++retries) {
    175    // Exponential backoff, so that we don't reject NACK because of time.
    176    clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
    177    backoff_factor *= 2;
    178    WaitForSendNack();
    179    EXPECT_EQ(retries + 1, sent_nacks_.size());
    180  }
    181 
    182  clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
    183  Flush();
    184  EXPECT_EQ(10u, sent_nacks_.size());
    185 }
    186 
    187 TEST_F(TestNackRequester, TooLargeNackList) {
    188  NackRequester& nack_module = CreateNackModule();
    189  nack_module.OnReceivedPacket(0);
    190  nack_module.OnReceivedPacket(1001);
    191  EXPECT_EQ(1000u, sent_nacks_.size());
    192  EXPECT_EQ(0, keyframes_requested_);
    193  nack_module.OnReceivedPacket(1003);
    194  EXPECT_EQ(1000u, sent_nacks_.size());
    195  EXPECT_EQ(1, keyframes_requested_);
    196  nack_module.OnReceivedPacket(1004);
    197  EXPECT_EQ(1000u, sent_nacks_.size());
    198  EXPECT_EQ(1, keyframes_requested_);
    199 }
    200 
    201 TEST_F(TestNackRequester, ClearUpTo) {
    202  NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
    203  nack_module.OnReceivedPacket(0);
    204  nack_module.OnReceivedPacket(100);
    205  EXPECT_EQ(99u, sent_nacks_.size());
    206 
    207  sent_nacks_.clear();
    208  clock_->AdvanceTimeMilliseconds(100);
    209  nack_module.ClearUpTo(50);
    210  WaitForSendNack();
    211  ASSERT_EQ(50u, sent_nacks_.size());
    212  EXPECT_EQ(50, sent_nacks_[0]);
    213 }
    214 
    215 TEST_F(TestNackRequester, ClearUpToWrap) {
    216  NackRequester& nack_module = CreateNackModule();
    217  nack_module.OnReceivedPacket(0xfff0);
    218  nack_module.OnReceivedPacket(0xf);
    219  EXPECT_EQ(30u, sent_nacks_.size());
    220 
    221  sent_nacks_.clear();
    222  clock_->AdvanceTimeMilliseconds(100);
    223  nack_module.ClearUpTo(0);
    224  WaitForSendNack();
    225  ASSERT_EQ(15u, sent_nacks_.size());
    226  EXPECT_EQ(0, sent_nacks_[0]);
    227 }
    228 
    229 TEST_F(TestNackRequester, PacketNackCount) {
    230  NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
    231  EXPECT_EQ(0, nack_module.OnReceivedPacket(0));
    232  EXPECT_EQ(0, nack_module.OnReceivedPacket(2));
    233  EXPECT_EQ(1, nack_module.OnReceivedPacket(1));
    234 
    235  sent_nacks_.clear();
    236  nack_module.UpdateRtt(100);
    237  EXPECT_EQ(0, nack_module.OnReceivedPacket(5));
    238  clock_->AdvanceTimeMilliseconds(100);
    239  WaitForSendNack();
    240  EXPECT_EQ(4u, sent_nacks_.size());
    241 
    242  clock_->AdvanceTimeMilliseconds(125);
    243  WaitForSendNack();
    244 
    245  EXPECT_EQ(6u, sent_nacks_.size());
    246 
    247  EXPECT_EQ(3, nack_module.OnReceivedPacket(3));
    248  EXPECT_EQ(3, nack_module.OnReceivedPacket(4));
    249  EXPECT_EQ(0, nack_module.OnReceivedPacket(4));
    250 }
    251 
    252 TEST_F(TestNackRequester, HandleFecRecoveredPacket) {
    253  NackRequester& nack_module = CreateNackModule();
    254  nack_module.OnReceivedPacket(1);
    255  nack_module.OnReceivedPacket(4, /*is_recovered=*/true);
    256  EXPECT_EQ(0u, sent_nacks_.size());
    257  nack_module.OnReceivedPacket(5);
    258  EXPECT_EQ(2u, sent_nacks_.size());
    259 }
    260 
    261 TEST_F(TestNackRequester, SendNackWithoutDelay) {
    262  NackRequester& nack_module = CreateNackModule();
    263  nack_module.OnReceivedPacket(0);
    264  nack_module.OnReceivedPacket(100);
    265  EXPECT_EQ(99u, sent_nacks_.size());
    266 }
    267 
    268 class TestNackRequesterWithFieldTrial : public ::testing::Test,
    269                                        public NackSender,
    270                                        public KeyFrameRequestSender {
    271 protected:
    272  TestNackRequesterWithFieldTrial()
    273      : clock_(new SimulatedClock(0)),
    274        nack_module_(TaskQueueBase::Current(),
    275                     &nack_periodic_processor_,
    276                     clock_.get(),
    277                     this,
    278                     this,
    279                     CreateTestFieldTrials("WebRTC-SendNackDelayMs/10/")),
    280        keyframes_requested_(0) {}
    281 
    282  void SendNack(const std::vector<uint16_t>& sequence_numbers,
    283                bool /* buffering_allowed */) override {
    284    sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
    285                       sequence_numbers.end());
    286  }
    287 
    288  void RequestKeyFrame() override { ++keyframes_requested_; }
    289 
    290  AutoThread main_thread_;
    291  std::unique_ptr<SimulatedClock> clock_;
    292  NackPeriodicProcessor nack_periodic_processor_;
    293  NackRequester nack_module_;
    294  std::vector<uint16_t> sent_nacks_;
    295  int keyframes_requested_;
    296 };
    297 
    298 TEST_F(TestNackRequesterWithFieldTrial, SendNackWithDelay) {
    299  nack_module_.OnReceivedPacket(0);
    300  nack_module_.OnReceivedPacket(100);
    301  EXPECT_EQ(0u, sent_nacks_.size());
    302  clock_->AdvanceTimeMilliseconds(10);
    303  nack_module_.OnReceivedPacket(106);
    304  EXPECT_EQ(99u, sent_nacks_.size());
    305  clock_->AdvanceTimeMilliseconds(10);
    306  nack_module_.OnReceivedPacket(109);
    307  EXPECT_EQ(104u, sent_nacks_.size());
    308 }
    309 }  // namespace webrtc