blob: 0e5d4159d38e4cdaff9a62470c3e45720273a9dc [file] [log] [blame]
Tommid3807da2020-05-22 17:36:36 +02001/*
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
Markus Handell06a2bf02021-07-22 15:09:39 +020011#include "modules/video_coding/nack_requester.h"
Tommid3807da2020-05-22 17:36:36 +020012
13#include <algorithm>
14#include <cstdint>
15#include <cstring>
16#include <memory>
17
18#include "system_wrappers/include/clock.h"
19#include "test/field_trial.h"
20#include "test/gtest.h"
Tommi63673fe2020-05-27 12:55:38 +020021#include "test/run_loop.h"
Tommid3807da2020-05-22 17:36:36 +020022
23namespace webrtc {
Tommi63673fe2020-05-27 12:55:38 +020024// TODO(bugs.webrtc.org/11594): Use the use the GlobalSimulatedTimeController
25// instead of RunLoop. At the moment we mix use of the Clock and the underlying
26// implementation of RunLoop, which is realtime.
Markus Handell06a2bf02021-07-22 15:09:39 +020027class TestNackRequester : public ::testing::TestWithParam<bool>,
28 public NackSender,
29 public KeyFrameRequestSender {
Tommid3807da2020-05-22 17:36:36 +020030 protected:
Markus Handell06a2bf02021-07-22 15:09:39 +020031 TestNackRequester()
Tommid3807da2020-05-22 17:36:36 +020032 : clock_(new SimulatedClock(0)),
33 field_trial_(GetParam()
34 ? "WebRTC-ExponentialNackBackoff/enabled:true/"
35 : "WebRTC-ExponentialNackBackoff/enabled:false/"),
Tommid3807da2020-05-22 17:36:36 +020036 keyframes_requested_(0) {}
37
Tommi63673fe2020-05-27 12:55:38 +020038 void SetUp() override {}
Tommid3807da2020-05-22 17:36:36 +020039
40 void SendNack(const std::vector<uint16_t>& sequence_numbers,
41 bool buffering_allowed) override {
42 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
43 sequence_numbers.end());
Tommi63673fe2020-05-27 12:55:38 +020044 if (waiting_for_send_nack_) {
45 waiting_for_send_nack_ = false;
46 loop_.Quit();
47 }
Tommid3807da2020-05-22 17:36:36 +020048 }
49
50 void RequestKeyFrame() override { ++keyframes_requested_; }
51
Tommi63673fe2020-05-27 12:55:38 +020052 void Flush() {
53 // nack_module.Process();
54 loop_.Flush();
55 }
56
57 bool WaitForSendNack() {
58 if (timed_out_) {
Artem Titovd3251962021-11-15 16:57:07 +010059 RTC_DCHECK_NOTREACHED();
Tommi63673fe2020-05-27 12:55:38 +020060 return false;
61 }
62
63 RTC_DCHECK(!waiting_for_send_nack_);
64
65 waiting_for_send_nack_ = true;
66 loop_.PostDelayedTask(
67 [this]() {
68 timed_out_ = true;
69 loop_.Quit();
70 },
71 1000);
72
73 loop_.Run();
74
75 if (timed_out_)
76 return false;
77
78 RTC_DCHECK(!waiting_for_send_nack_);
79 return true;
80 }
81
Markus Handell06a2bf02021-07-22 15:09:39 +020082 NackRequester& CreateNackModule(
Markus Handell0e62f7a2021-07-20 13:32:02 +020083 TimeDelta interval = NackPeriodicProcessor::kUpdateInterval) {
Tommi63673fe2020-05-27 12:55:38 +020084 RTC_DCHECK(!nack_module_.get());
Markus Handell0e62f7a2021-07-20 13:32:02 +020085 nack_periodic_processor_ =
86 std::make_unique<NackPeriodicProcessor>(interval);
Markus Handell06a2bf02021-07-22 15:09:39 +020087 nack_module_ = std::make_unique<NackRequester>(
88 TaskQueueBase::Current(), nack_periodic_processor_.get(), clock_.get(),
89 this, this);
Tommi63673fe2020-05-27 12:55:38 +020090 nack_module_->UpdateRtt(kDefaultRttMs);
91 return *nack_module_.get();
92 }
93
Tommid3807da2020-05-22 17:36:36 +020094 static constexpr int64_t kDefaultRttMs = 20;
Tommi63673fe2020-05-27 12:55:38 +020095 test::RunLoop loop_;
Tommid3807da2020-05-22 17:36:36 +020096 std::unique_ptr<SimulatedClock> clock_;
97 test::ScopedFieldTrials field_trial_;
Markus Handell0e62f7a2021-07-20 13:32:02 +020098 std::unique_ptr<NackPeriodicProcessor> nack_periodic_processor_;
Markus Handell06a2bf02021-07-22 15:09:39 +020099 std::unique_ptr<NackRequester> nack_module_;
Tommid3807da2020-05-22 17:36:36 +0200100 std::vector<uint16_t> sent_nacks_;
101 int keyframes_requested_;
Tommi63673fe2020-05-27 12:55:38 +0200102 bool waiting_for_send_nack_ = false;
103 bool timed_out_ = false;
Tommid3807da2020-05-22 17:36:36 +0200104};
105
Markus Handell06a2bf02021-07-22 15:09:39 +0200106TEST_P(TestNackRequester, NackOnePacket) {
107 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200108 nack_module.OnReceivedPacket(1, false, false);
109 nack_module.OnReceivedPacket(3, false, false);
110 ASSERT_EQ(1u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200111 EXPECT_EQ(2, sent_nacks_[0]);
112}
113
Markus Handell06a2bf02021-07-22 15:09:39 +0200114TEST_P(TestNackRequester, WrappingSeqNum) {
115 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200116 nack_module.OnReceivedPacket(0xfffe, false, false);
117 nack_module.OnReceivedPacket(1, false, false);
118 ASSERT_EQ(2u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200119 EXPECT_EQ(0xffff, sent_nacks_[0]);
120 EXPECT_EQ(0, sent_nacks_[1]);
121}
122
Markus Handell06a2bf02021-07-22 15:09:39 +0200123TEST_P(TestNackRequester, WrappingSeqNumClearToKeyframe) {
124 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(10));
Tommi63673fe2020-05-27 12:55:38 +0200125 nack_module.OnReceivedPacket(0xfffe, false, false);
126 nack_module.OnReceivedPacket(1, false, false);
127 ASSERT_EQ(2u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200128 EXPECT_EQ(0xffff, sent_nacks_[0]);
129 EXPECT_EQ(0, sent_nacks_[1]);
130
131 sent_nacks_.clear();
Tommi63673fe2020-05-27 12:55:38 +0200132 nack_module.OnReceivedPacket(2, true, false);
133 ASSERT_EQ(0u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200134
Tommi63673fe2020-05-27 12:55:38 +0200135 nack_module.OnReceivedPacket(501, true, false);
136 ASSERT_EQ(498u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200137 for (int seq_num = 3; seq_num < 501; ++seq_num)
138 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
139
140 sent_nacks_.clear();
Tommi63673fe2020-05-27 12:55:38 +0200141 nack_module.OnReceivedPacket(1001, false, false);
Tommid3807da2020-05-22 17:36:36 +0200142 EXPECT_EQ(499u, sent_nacks_.size());
143 for (int seq_num = 502; seq_num < 1001; ++seq_num)
144 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
145
146 sent_nacks_.clear();
147 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200148 ASSERT_TRUE(WaitForSendNack());
149 ASSERT_EQ(999u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200150 EXPECT_EQ(0xffff, sent_nacks_[0]);
151 EXPECT_EQ(0, sent_nacks_[1]);
152 for (int seq_num = 3; seq_num < 501; ++seq_num)
153 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 1]);
154 for (int seq_num = 502; seq_num < 1001; ++seq_num)
155 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 2]);
156
157 // Adding packet 1004 will cause the nack list to reach it's max limit.
158 // It will then clear all nacks up to the next keyframe (seq num 2),
159 // thus removing 0xffff and 0 from the nack list.
160 sent_nacks_.clear();
Tommi63673fe2020-05-27 12:55:38 +0200161 nack_module.OnReceivedPacket(1004, false, false);
162 ASSERT_EQ(2u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200163 EXPECT_EQ(1002, sent_nacks_[0]);
164 EXPECT_EQ(1003, sent_nacks_[1]);
165
166 sent_nacks_.clear();
167 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200168 ASSERT_TRUE(WaitForSendNack());
169 ASSERT_EQ(999u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200170 for (int seq_num = 3; seq_num < 501; ++seq_num)
171 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
172 for (int seq_num = 502; seq_num < 1001; ++seq_num)
173 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 4]);
174
175 // Adding packet 1007 will cause the nack module to overflow again, thus
176 // clearing everything up to 501 which is the next keyframe.
Tommi63673fe2020-05-27 12:55:38 +0200177 nack_module.OnReceivedPacket(1007, false, false);
Tommid3807da2020-05-22 17:36:36 +0200178 sent_nacks_.clear();
179 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200180 ASSERT_TRUE(WaitForSendNack());
181 ASSERT_EQ(503u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200182 for (int seq_num = 502; seq_num < 1001; ++seq_num)
183 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
184 EXPECT_EQ(1005, sent_nacks_[501]);
185 EXPECT_EQ(1006, sent_nacks_[502]);
186}
187
Markus Handell06a2bf02021-07-22 15:09:39 +0200188TEST_P(TestNackRequester, ResendNack) {
189 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
Tommi63673fe2020-05-27 12:55:38 +0200190 nack_module.OnReceivedPacket(1, false, false);
191 nack_module.OnReceivedPacket(3, false, false);
Tommid3807da2020-05-22 17:36:36 +0200192 size_t expected_nacks_sent = 1;
Tommi63673fe2020-05-27 12:55:38 +0200193 ASSERT_EQ(expected_nacks_sent, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200194 EXPECT_EQ(2, sent_nacks_[0]);
195
196 if (GetParam()) {
197 // Retry has to wait at least 5ms by default.
Tommi63673fe2020-05-27 12:55:38 +0200198 nack_module.UpdateRtt(1);
Tommid3807da2020-05-22 17:36:36 +0200199 clock_->AdvanceTimeMilliseconds(4);
Tommi63673fe2020-05-27 12:55:38 +0200200 Flush(); // Too early.
Tommid3807da2020-05-22 17:36:36 +0200201 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
202
203 clock_->AdvanceTimeMilliseconds(1);
Tommi63673fe2020-05-27 12:55:38 +0200204 WaitForSendNack(); // Now allowed.
Tommid3807da2020-05-22 17:36:36 +0200205 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
206 } else {
Tommi63673fe2020-05-27 12:55:38 +0200207 nack_module.UpdateRtt(1);
Tommid3807da2020-05-22 17:36:36 +0200208 clock_->AdvanceTimeMilliseconds(1);
Tommi63673fe2020-05-27 12:55:38 +0200209 WaitForSendNack(); // Fast retransmit allowed.
Tommid3807da2020-05-22 17:36:36 +0200210 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
211 }
212
213 // N:th try has to wait b^(N-1) * rtt by default.
214 const double b = GetParam() ? 1.25 : 1.0;
215 for (int i = 2; i < 10; ++i) {
216 // Change RTT, above the 40ms max for exponential backoff.
217 TimeDelta rtt = TimeDelta::Millis(160); // + (i * 10 - 40)
Tommi63673fe2020-05-27 12:55:38 +0200218 nack_module.UpdateRtt(rtt.ms());
Tommid3807da2020-05-22 17:36:36 +0200219
220 // RTT gets capped at 160ms in backoff calculations.
221 TimeDelta expected_backoff_delay =
222 std::pow(b, i - 1) * std::min(rtt, TimeDelta::Millis(160));
223
224 // Move to one millisecond before next allowed NACK.
225 clock_->AdvanceTimeMilliseconds(expected_backoff_delay.ms() - 1);
Tommi63673fe2020-05-27 12:55:38 +0200226 Flush();
Tommid3807da2020-05-22 17:36:36 +0200227 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
228
229 // Move to one millisecond after next allowed NACK.
230 // After rather than on to avoid rounding errors.
231 clock_->AdvanceTimeMilliseconds(2);
Tommi63673fe2020-05-27 12:55:38 +0200232 WaitForSendNack(); // Now allowed.
Tommid3807da2020-05-22 17:36:36 +0200233 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
234 }
235
236 // Giving up after 10 tries.
237 clock_->AdvanceTimeMilliseconds(3000);
Tommi63673fe2020-05-27 12:55:38 +0200238 Flush();
Tommid3807da2020-05-22 17:36:36 +0200239 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
240}
241
Markus Handell06a2bf02021-07-22 15:09:39 +0200242TEST_P(TestNackRequester, ResendPacketMaxRetries) {
243 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
Tommi63673fe2020-05-27 12:55:38 +0200244 nack_module.OnReceivedPacket(1, false, false);
245 nack_module.OnReceivedPacket(3, false, false);
246 ASSERT_EQ(1u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200247 EXPECT_EQ(2, sent_nacks_[0]);
248
249 int backoff_factor = 1;
250 for (size_t retries = 1; retries < 10; ++retries) {
251 // Exponential backoff, so that we don't reject NACK because of time.
252 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
253 backoff_factor *= 2;
Tommi63673fe2020-05-27 12:55:38 +0200254 WaitForSendNack();
Tommid3807da2020-05-22 17:36:36 +0200255 EXPECT_EQ(retries + 1, sent_nacks_.size());
256 }
257
258 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
Tommi63673fe2020-05-27 12:55:38 +0200259 Flush();
Tommid3807da2020-05-22 17:36:36 +0200260 EXPECT_EQ(10u, sent_nacks_.size());
261}
262
Markus Handell06a2bf02021-07-22 15:09:39 +0200263TEST_P(TestNackRequester, TooLargeNackList) {
264 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200265 nack_module.OnReceivedPacket(0, false, false);
266 nack_module.OnReceivedPacket(1001, false, false);
Tommid3807da2020-05-22 17:36:36 +0200267 EXPECT_EQ(1000u, sent_nacks_.size());
268 EXPECT_EQ(0, keyframes_requested_);
Tommi63673fe2020-05-27 12:55:38 +0200269 nack_module.OnReceivedPacket(1003, false, false);
Tommid3807da2020-05-22 17:36:36 +0200270 EXPECT_EQ(1000u, sent_nacks_.size());
271 EXPECT_EQ(1, keyframes_requested_);
Tommi63673fe2020-05-27 12:55:38 +0200272 nack_module.OnReceivedPacket(1004, false, false);
Tommid3807da2020-05-22 17:36:36 +0200273 EXPECT_EQ(1000u, sent_nacks_.size());
274 EXPECT_EQ(1, keyframes_requested_);
275}
276
Markus Handell06a2bf02021-07-22 15:09:39 +0200277TEST_P(TestNackRequester, TooLargeNackListWithKeyFrame) {
278 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200279 nack_module.OnReceivedPacket(0, false, false);
280 nack_module.OnReceivedPacket(1, true, false);
281 nack_module.OnReceivedPacket(1001, false, false);
Tommid3807da2020-05-22 17:36:36 +0200282 EXPECT_EQ(999u, sent_nacks_.size());
283 EXPECT_EQ(0, keyframes_requested_);
Tommi63673fe2020-05-27 12:55:38 +0200284 nack_module.OnReceivedPacket(1003, false, false);
Tommid3807da2020-05-22 17:36:36 +0200285 EXPECT_EQ(1000u, sent_nacks_.size());
286 EXPECT_EQ(0, keyframes_requested_);
Tommi63673fe2020-05-27 12:55:38 +0200287 nack_module.OnReceivedPacket(1005, false, false);
Tommid3807da2020-05-22 17:36:36 +0200288 EXPECT_EQ(1000u, sent_nacks_.size());
289 EXPECT_EQ(1, keyframes_requested_);
290}
291
Markus Handell06a2bf02021-07-22 15:09:39 +0200292TEST_P(TestNackRequester, ClearUpTo) {
293 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
Tommi63673fe2020-05-27 12:55:38 +0200294 nack_module.OnReceivedPacket(0, false, false);
295 nack_module.OnReceivedPacket(100, false, false);
Tommid3807da2020-05-22 17:36:36 +0200296 EXPECT_EQ(99u, sent_nacks_.size());
297
298 sent_nacks_.clear();
299 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200300 nack_module.ClearUpTo(50);
301 WaitForSendNack();
302 ASSERT_EQ(50u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200303 EXPECT_EQ(50, sent_nacks_[0]);
304}
305
Markus Handell06a2bf02021-07-22 15:09:39 +0200306TEST_P(TestNackRequester, ClearUpToWrap) {
307 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200308 nack_module.OnReceivedPacket(0xfff0, false, false);
309 nack_module.OnReceivedPacket(0xf, false, false);
Tommid3807da2020-05-22 17:36:36 +0200310 EXPECT_EQ(30u, sent_nacks_.size());
311
312 sent_nacks_.clear();
313 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200314 nack_module.ClearUpTo(0);
315 WaitForSendNack();
316 ASSERT_EQ(15u, sent_nacks_.size());
Tommid3807da2020-05-22 17:36:36 +0200317 EXPECT_EQ(0, sent_nacks_[0]);
318}
319
Markus Handell06a2bf02021-07-22 15:09:39 +0200320TEST_P(TestNackRequester, PacketNackCount) {
321 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1));
Tommi63673fe2020-05-27 12:55:38 +0200322 EXPECT_EQ(0, nack_module.OnReceivedPacket(0, false, false));
323 EXPECT_EQ(0, nack_module.OnReceivedPacket(2, false, false));
324 EXPECT_EQ(1, nack_module.OnReceivedPacket(1, false, false));
Tommid3807da2020-05-22 17:36:36 +0200325
326 sent_nacks_.clear();
Tommi63673fe2020-05-27 12:55:38 +0200327 nack_module.UpdateRtt(100);
328 EXPECT_EQ(0, nack_module.OnReceivedPacket(5, false, false));
Tommid3807da2020-05-22 17:36:36 +0200329 clock_->AdvanceTimeMilliseconds(100);
Tommi63673fe2020-05-27 12:55:38 +0200330 WaitForSendNack();
331 EXPECT_EQ(4u, sent_nacks_.size());
332
Tommid3807da2020-05-22 17:36:36 +0200333 clock_->AdvanceTimeMilliseconds(125);
Tommi63673fe2020-05-27 12:55:38 +0200334 WaitForSendNack();
335
336 EXPECT_EQ(6u, sent_nacks_.size());
337
338 EXPECT_EQ(3, nack_module.OnReceivedPacket(3, false, false));
339 EXPECT_EQ(3, nack_module.OnReceivedPacket(4, false, false));
340 EXPECT_EQ(0, nack_module.OnReceivedPacket(4, false, false));
Tommid3807da2020-05-22 17:36:36 +0200341}
342
Markus Handell06a2bf02021-07-22 15:09:39 +0200343TEST_P(TestNackRequester, NackListFullAndNoOverlapWithKeyframes) {
344 NackRequester& nack_module = CreateNackModule();
Tommid3807da2020-05-22 17:36:36 +0200345 const int kMaxNackPackets = 1000;
346 const unsigned int kFirstGap = kMaxNackPackets - 20;
347 const unsigned int kSecondGap = 200;
348 uint16_t seq_num = 0;
Tommi63673fe2020-05-27 12:55:38 +0200349 nack_module.OnReceivedPacket(seq_num++, true, false);
Tommid3807da2020-05-22 17:36:36 +0200350 seq_num += kFirstGap;
Tommi63673fe2020-05-27 12:55:38 +0200351 nack_module.OnReceivedPacket(seq_num++, true, false);
Tommid3807da2020-05-22 17:36:36 +0200352 EXPECT_EQ(kFirstGap, sent_nacks_.size());
353 sent_nacks_.clear();
354 seq_num += kSecondGap;
Tommi63673fe2020-05-27 12:55:38 +0200355 nack_module.OnReceivedPacket(seq_num, true, false);
Tommid3807da2020-05-22 17:36:36 +0200356 EXPECT_EQ(kSecondGap, sent_nacks_.size());
357}
358
Markus Handell06a2bf02021-07-22 15:09:39 +0200359TEST_P(TestNackRequester, HandleFecRecoveredPacket) {
360 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200361 nack_module.OnReceivedPacket(1, false, false);
362 nack_module.OnReceivedPacket(4, false, true);
Tommid3807da2020-05-22 17:36:36 +0200363 EXPECT_EQ(0u, sent_nacks_.size());
Tommi63673fe2020-05-27 12:55:38 +0200364 nack_module.OnReceivedPacket(5, false, false);
Tommid3807da2020-05-22 17:36:36 +0200365 EXPECT_EQ(2u, sent_nacks_.size());
366}
367
Markus Handell06a2bf02021-07-22 15:09:39 +0200368TEST_P(TestNackRequester, SendNackWithoutDelay) {
369 NackRequester& nack_module = CreateNackModule();
Tommi63673fe2020-05-27 12:55:38 +0200370 nack_module.OnReceivedPacket(0, false, false);
371 nack_module.OnReceivedPacket(100, false, false);
Tommid3807da2020-05-22 17:36:36 +0200372 EXPECT_EQ(99u, sent_nacks_.size());
373}
374
375INSTANTIATE_TEST_SUITE_P(WithAndWithoutBackoff,
Markus Handell06a2bf02021-07-22 15:09:39 +0200376 TestNackRequester,
Tommid3807da2020-05-22 17:36:36 +0200377 ::testing::Values(true, false));
378
Markus Handell06a2bf02021-07-22 15:09:39 +0200379class TestNackRequesterWithFieldTrial : public ::testing::Test,
380 public NackSender,
381 public KeyFrameRequestSender {
Tommid3807da2020-05-22 17:36:36 +0200382 protected:
Markus Handell06a2bf02021-07-22 15:09:39 +0200383 TestNackRequesterWithFieldTrial()
Tommid3807da2020-05-22 17:36:36 +0200384 : nack_delay_field_trial_("WebRTC-SendNackDelayMs/10/"),
385 clock_(new SimulatedClock(0)),
Markus Handell0e62f7a2021-07-20 13:32:02 +0200386 nack_module_(TaskQueueBase::Current(),
387 &nack_periodic_processor_,
388 clock_.get(),
389 this,
390 this),
Tommid3807da2020-05-22 17:36:36 +0200391 keyframes_requested_(0) {}
392
393 void SendNack(const std::vector<uint16_t>& sequence_numbers,
394 bool buffering_allowed) override {
395 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
396 sequence_numbers.end());
397 }
398
399 void RequestKeyFrame() override { ++keyframes_requested_; }
400
401 test::ScopedFieldTrials nack_delay_field_trial_;
402 std::unique_ptr<SimulatedClock> clock_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200403 NackPeriodicProcessor nack_periodic_processor_;
Markus Handell06a2bf02021-07-22 15:09:39 +0200404 NackRequester nack_module_;
Tommid3807da2020-05-22 17:36:36 +0200405 std::vector<uint16_t> sent_nacks_;
406 int keyframes_requested_;
407};
408
Markus Handell06a2bf02021-07-22 15:09:39 +0200409TEST_F(TestNackRequesterWithFieldTrial, SendNackWithDelay) {
Tommid3807da2020-05-22 17:36:36 +0200410 nack_module_.OnReceivedPacket(0, false, false);
411 nack_module_.OnReceivedPacket(100, false, false);
412 EXPECT_EQ(0u, sent_nacks_.size());
413 clock_->AdvanceTimeMilliseconds(10);
414 nack_module_.OnReceivedPacket(106, false, false);
415 EXPECT_EQ(99u, sent_nacks_.size());
416 clock_->AdvanceTimeMilliseconds(10);
417 nack_module_.OnReceivedPacket(109, false, false);
418 EXPECT_EQ(104u, sent_nacks_.size());
419}
420} // namespace webrtc