blob: d235bb189ec9d2d8c6cb4047b296305f626ba4f4 [file] [log] [blame]
Weiwei Liu245d7912016-07-28 00:04:25 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoe9c69852017-11-04 18:08:37 -04002/*
Davide Pesavento958896e2017-01-19 00:52:04 -05003 * Copyright (c) 2016-2017, Regents of the University of California,
4 * Colorado State University,
5 * University Pierre & Marie Curie, Sorbonne University.
Weiwei Liu245d7912016-07-28 00:04:25 -07006 *
7 * This file is part of ndn-tools (Named Data Networking Essential Tools).
8 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
9 *
10 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
22 *
23 * @author Weiwei Liu
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000024 * @author Chavoosh Ghasemi
Weiwei Liu245d7912016-07-28 00:04:25 -070025 */
26
27#include "tools/chunks/catchunks/pipeline-interests-aimd.hpp"
28#include "tools/chunks/catchunks/options.hpp"
29
30#include "pipeline-interests-fixture.hpp"
31
32namespace ndn {
33namespace chunks {
34namespace aimd {
35namespace tests {
36
37using namespace ndn::tests;
38
39class PipelineInterestAimdFixture : public ndn::chunks::tests::PipelineInterestsFixture
40{
41public:
42 PipelineInterestAimdFixture()
43 : PipelineInterestsFixture()
44 , opt(makePipelineOptions())
45 , rttEstimator(makeRttEstimatorOptions())
46 {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000047 createPipeline();
48 }
49
50 void
51 createPipeline()
52 {
Weiwei Liu245d7912016-07-28 00:04:25 -070053 auto pline = make_unique<PipelineInterestsAimd>(face, rttEstimator, opt);
54 aimdPipeline = pline.get();
55 setPipeline(std::move(pline));
56 }
57
58private:
59 static PipelineInterestsAimdOptions
60 makePipelineOptions()
61 {
62 PipelineInterestsAimdOptions pipelineOptions;
63 pipelineOptions.disableCwa = false;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000064 pipelineOptions.ignoreCongMarks = false;
Weiwei Liu245d7912016-07-28 00:04:25 -070065 pipelineOptions.resetCwndToInit = false;
66 pipelineOptions.initCwnd = 1.0;
67 pipelineOptions.aiStep = 1.0;
68 pipelineOptions.mdCoef = 0.5;
69 pipelineOptions.initSsthresh = std::numeric_limits<int>::max();
70 return pipelineOptions;
71 }
72
73 static RttEstimator::Options
74 makeRttEstimatorOptions()
75 {
76 RttEstimator::Options rttOptions;
77 rttOptions.alpha = 0.125;
78 rttOptions.beta = 0.25;
79 rttOptions.k = 4;
80 rttOptions.minRto = Milliseconds(200);
81 rttOptions.maxRto = Milliseconds(4000);
82 return rttOptions;
83 }
84
85protected:
86 PipelineInterestsAimdOptions opt;
87 RttEstimator rttEstimator;
88 PipelineInterestsAimd* aimdPipeline;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000089 static constexpr double MARGIN = 0.01;
Weiwei Liu245d7912016-07-28 00:04:25 -070090};
91
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000092constexpr double PipelineInterestAimdFixture::MARGIN;
93
Weiwei Liu245d7912016-07-28 00:04:25 -070094BOOST_AUTO_TEST_SUITE(Chunks)
95BOOST_FIXTURE_TEST_SUITE(TestPipelineInterestsAimd, PipelineInterestAimdFixture)
96
97BOOST_AUTO_TEST_CASE(SlowStart)
98{
99 nDataSegments = 4;
100 aimdPipeline->m_ssthresh = 8.0;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000101 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700102
103 double preCwnd = aimdPipeline->m_cwnd;
104 runWithData(*makeDataWithSegment(0));
105 advanceClocks(io, time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400106 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700107
108 for (uint64_t i = 1; i < nDataSegments - 1; ++i) {
109 face.receive(*makeDataWithSegment(i));
110 advanceClocks(io, time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000111 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd - preCwnd, 1, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700112 preCwnd = aimdPipeline->m_cwnd;
113 }
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400114
115 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments - 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700116}
117
118BOOST_AUTO_TEST_CASE(CongestionAvoidance)
119{
120 nDataSegments = 8;
121 aimdPipeline->m_ssthresh = 4.0;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000122 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700123
124 double preCwnd = aimdPipeline->m_cwnd;
125 runWithData(*makeDataWithSegment(0));
126 advanceClocks(io, time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400127 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700128
129 for (uint64_t i = 1; i < aimdPipeline->m_ssthresh; ++i) { // slow start
130 face.receive(*makeDataWithSegment(i));
131 advanceClocks(io, time::nanoseconds(1));
132 preCwnd = aimdPipeline->m_cwnd;
133 }
134
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000135 BOOST_CHECK_CLOSE(preCwnd, aimdPipeline->m_ssthresh, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700136
137 for (uint64_t i = aimdPipeline->m_ssthresh; i < nDataSegments - 1; ++i) { // congestion avoidance
138 face.receive(*makeDataWithSegment(i));
139 advanceClocks(io, time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000140 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd - preCwnd, opt.aiStep / floor(aimdPipeline->m_cwnd), MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700141 preCwnd = aimdPipeline->m_cwnd;
142 }
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400143
144 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments - 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700145}
146
147BOOST_AUTO_TEST_CASE(Timeout)
148{
149 nDataSegments = 8;
150 aimdPipeline->m_ssthresh = 4.0;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000151 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700152
153 runWithData(*makeDataWithSegment(0));
154 advanceClocks(io, time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400155 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700156
157 // receive segment 1 and segment 2
158 for (uint64_t i = 1; i < 3; ++i) {
159 face.receive(*makeDataWithSegment(i));
160 advanceClocks(io, time::nanoseconds(1));
161 }
162
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400163 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 3);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000164 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 3, MARGIN);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400165 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5); // request for segment 5 has been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700166
167 advanceClocks(io, time::milliseconds(100));
168
169 // receive segment 4
170 face.receive(*makeDataWithSegment(4));
171 advanceClocks(io, time::nanoseconds(1));
172
173 // receive segment 5
174 face.receive(*makeDataWithSegment(5));
175 advanceClocks(io, time::nanoseconds(1));
176
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400177 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000178 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 4.25, MARGIN);
179 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1); // all the segment requests have been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700180
181 // timeout segment 3
182 advanceClocks(io, time::milliseconds(150));
183
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400184 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000185 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 2.125, MARGIN); // window size drop to 1/2 of previous size
Weiwei Liu245d7912016-07-28 00:04:25 -0700186 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 1);
187
188 // receive segment 6, retransmit 3
189 face.receive(*makeDataWithSegment(6));
190 advanceClocks(io, time::nanoseconds(1));
191
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400192 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000193 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 2.625, MARGIN); // congestion avoidance
Weiwei Liu245d7912016-07-28 00:04:25 -0700194 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 0);
195 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[3], 1);
196}
197
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000198BOOST_AUTO_TEST_CASE(CongestionMarksWithCwa)
199{
200 nDataSegments = 7;
201 aimdPipeline->m_ssthresh = 4.0;
202 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
203
204 runWithData(*makeDataWithSegment(0));
205 advanceClocks(io, time::nanoseconds(1));
206 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
207
208 // receive segments 1 to 4
209 for (uint64_t i = 1; i < 5; ++i) {
210 face.receive(*makeDataWithSegment(i));
211 advanceClocks(io, time::nanoseconds(1));
212 }
213
214 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
215 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 4.25, MARGIN);
216
217 // receive segment 5 with congestion mark
218 face.receive(*makeDataWithSegmentAndCongMark(5));
219 advanceClocks(io, time::nanoseconds(1));
220
221 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
222 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 2.125, MARGIN); // window size drops to 1/2 of previous size
223 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1); // all interests have been sent
224
225 // receive the last segment with congestion mark
226 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
227 advanceClocks(io, time::nanoseconds(1));
228
229 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
230 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 2.125, MARGIN); // conservative window adaption (window size should not decrease)
231 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 0);
232
233 // make sure no interest is retransmitted for marked data packets
234 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[5], 0);
235 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[nDataSegments - 1], 0);
236
237 // check number of received marked data packets
238 BOOST_CHECK_EQUAL(aimdPipeline->m_nCongMarks, 2);
239}
240
241BOOST_AUTO_TEST_CASE(CongestionMarksWithoutCwa)
242{
243 opt.disableCwa = true;
244 createPipeline();
245
246 nDataSegments = 7;
247 aimdPipeline->m_ssthresh = 4.0;
248 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
249
250 runWithData(*makeDataWithSegment(0));
251 advanceClocks(io, time::nanoseconds(1));
252 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
253
254 // receive segments 1 to 4
255 for (uint64_t i = 1; i < 5; ++i) {
256 face.receive(*makeDataWithSegment(i));
257 advanceClocks(io, time::nanoseconds(1));
258 }
259
260 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
261 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 4.25, MARGIN);
262
263 // receive segment 5 with congestion mark
264 face.receive(*makeDataWithSegmentAndCongMark(5));
265 advanceClocks(io, time::nanoseconds(1));
266
267 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
268 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 2.125, MARGIN); // window size drops to 1/2 of previous size
269 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1); // all interests have been sent
270
271 // receive the last segment with congestion mark
272 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
273 advanceClocks(io, time::nanoseconds(1));
274
275 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
276 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, PipelineInterestsAimd::MIN_SSTHRESH,
277 MARGIN); // window size should decrease, as cwa is disabled
278 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 0);
279
280 // make sure no interest is retransmitted for marked data packets
281 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[5], 0);
282 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[nDataSegments - 1], 0);
283
284 // check number of received marked data packets
285 BOOST_CHECK_EQUAL(aimdPipeline->m_nCongMarks, 2);
286}
287
288BOOST_AUTO_TEST_CASE(IgnoreCongestionMarks)
289{
290 opt.ignoreCongMarks = true;
291 createPipeline();
292
293 nDataSegments = 7;
294 aimdPipeline->m_ssthresh = 4.0;
295 BOOST_REQUIRE_CLOSE(aimdPipeline->m_cwnd, 1, MARGIN);
296
297 runWithData(*makeDataWithSegment(0));
298 advanceClocks(io, time::nanoseconds(1));
299 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
300
301 // receive segments 1 to 5
302 for (uint64_t i = 1; i < 6; ++i) {
303 face.receive(*makeDataWithSegment(i));
304 advanceClocks(io, time::nanoseconds(1));
305 }
306
307 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
308 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 4.5, MARGIN);
309 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1); // all interests have been sent
310
311 // receive the last segment with congestion mark
312 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
313 advanceClocks(io, time::nanoseconds(1));
314
315 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
316 BOOST_CHECK_CLOSE(aimdPipeline->m_cwnd, 4.75, MARGIN); // window size increases
317 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 0);
318
319 // make sure no interest is retransmitted for marked data packet
320 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[nDataSegments - 1], 0);
321
322 // check number of received marked data packets
323 BOOST_CHECK_EQUAL(aimdPipeline->m_nCongMarks, 1);
324}
325
Weiwei Liu245d7912016-07-28 00:04:25 -0700326BOOST_AUTO_TEST_CASE(Nack)
327{
328 nDataSegments = 5;
329 aimdPipeline->m_cwnd = 10.0;
330 runWithData(*makeDataWithSegment(0));
331 advanceClocks(io, time::nanoseconds(1));
332
333 face.receive(*makeDataWithSegment(1));
334 advanceClocks(io, time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400335
336 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700337 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 4);
338
339 // receive a nack with NackReason::DUPLICATE for segment 2
340 auto nack1 = makeNack(face.sentInterests[1], lp::NackReason::DUPLICATE);
341 face.receive(nack1);
342 advanceClocks(io, time::nanoseconds(1));
343
344 // nack1 is ignored
345 BOOST_CHECK_EQUAL(hasFailed, false);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400346 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700347 BOOST_CHECK_EQUAL(aimdPipeline->m_retxQueue.size(), 0);
348
349 // receive a nack with NackReason::CONGESTION for segment 3
350 auto nack2 = makeNack(face.sentInterests[2], lp::NackReason::CONGESTION);
351 face.receive(nack2);
352 advanceClocks(io, time::nanoseconds(1));
353
354 // segment 3 is retransmitted
355 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[3], 1);
356
357 // receive a nack with NackReason::NONE for segment 4
358 auto nack3 = makeNack(face.sentInterests[3], lp::NackReason::NONE);
359 face.receive(nack3);
360 advanceClocks(io, time::nanoseconds(1));
361
362 // Other types of Nack will trigger a failure
363 BOOST_CHECK_EQUAL(hasFailed, true);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400364 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700365}
366
367BOOST_AUTO_TEST_CASE(FinalBlockIdNotSetAtBeginning)
368{
369 nDataSegments = 4;
370 aimdPipeline->m_cwnd = 4;
371 runWithData(*makeDataWithSegment(0, false));
372 advanceClocks(io, time::nanoseconds(1));
373
374 // receive segment 1 without FinalBlockId
375 face.receive(*makeDataWithSegment(1, false));
376 advanceClocks(io, time::nanoseconds(1));
377
378 // interests for segment 1 - 6 have been sent
379 BOOST_CHECK_EQUAL(face.sentInterests.size(), 6);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400380 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700381 BOOST_CHECK_EQUAL(aimdPipeline->m_hasFinalBlockId, false);
382 // pending interests: segment 2, 3, 4, 5, 6
383 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 5);
384
385 // receive segment 2 with FinalBlockId
386 face.receive(*makeDataWithSegment(2));
387 advanceClocks(io, time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400388 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 3);
Weiwei Liu245d7912016-07-28 00:04:25 -0700389 BOOST_CHECK_EQUAL(aimdPipeline->m_hasFinalBlockId, true);
390
391 // pending interests for segment 2, 4, 5, 6 haven been removed
392 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
393}
394
395BOOST_AUTO_TEST_CASE(FailureBeforeFinalBlockIdReceived)
396{
397 // failed to retrieve segNo while the FinalBlockId has not yet been
398 // set, and later received a FinalBlockId >= segNo, i.e. segNo is
399 // part of the content.
400
401 nDataSegments = 4;
402 aimdPipeline->m_cwnd = 4;
403 runWithData(*makeDataWithSegment(0, false));
404 advanceClocks(io, time::nanoseconds(1));
405
406 // receive segment 1 without FinalBlockId
407 face.receive(*makeDataWithSegment(1, false));
408 advanceClocks(io, time::nanoseconds(1));
409 // interests for segment 1 - 6 have been sent
410 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 6);
411
412 // receive nack with NackReason::NONE for segment 3
413 auto nack = makeNack(face.sentInterests[2], lp::NackReason::NONE);
414 face.receive(nack);
415 advanceClocks(io, time::nanoseconds(1));
416
417 // error not triggered
418 // pending interests for segment > 3 haven been removed
419 BOOST_CHECK_EQUAL(hasFailed, false);
420 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
421
422 // receive segment 2 with FinalBlockId
423 face.receive(*makeDataWithSegment(2));
424 advanceClocks(io, time::nanoseconds(1));
425
426 // error triggered since segment 3 is part of the content
427 BOOST_CHECK_EQUAL(hasFailed, true);
428}
429
430BOOST_AUTO_TEST_CASE(SpuriousFailureBeforeFinalBlockIdReceived)
431{
432 // failed to retrieve segNo while the FinalBlockId has not yet been
433 // set, and later received a FinalBlockId < segNo, i.e. segNo is
434 // not part of the content, and it was actually a spurious failure
435
436 nDataSegments = 4;
437 aimdPipeline->m_cwnd = 4;
438 runWithData(*makeDataWithSegment(0, false));
439 advanceClocks(io, time::nanoseconds(1));
440
441 // receive segment 1 without FinalBlockId
442 face.receive(*makeDataWithSegment(1, false));
443 advanceClocks(io, time::nanoseconds(1));
444 // interests for segment 1 - 6 have been sent
445 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 6);
446
447 // receive nack with NackReason::NONE for segment 4
Davide Pesavento958896e2017-01-19 00:52:04 -0500448 auto nack = makeNack(face.sentInterests[3], lp::NackReason::NONE);
Weiwei Liu245d7912016-07-28 00:04:25 -0700449 face.receive(nack);
450 advanceClocks(io, time::nanoseconds(1));
451
452 // error not triggered
Davide Pesavento958896e2017-01-19 00:52:04 -0500453 // pending interests for segment > 4 have been removed
Weiwei Liu245d7912016-07-28 00:04:25 -0700454 BOOST_CHECK_EQUAL(hasFailed, false);
455 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 2);
456
457 // receive segment 2 with FinalBlockId
458 face.receive(*makeDataWithSegment(2));
459 advanceClocks(io, time::nanoseconds(1));
460
461 // timeout segment 3
Davide Pesavento958896e2017-01-19 00:52:04 -0500462 advanceClocks(io, time::seconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700463
464 // segment 3 is retransmitted
465 BOOST_CHECK_EQUAL(aimdPipeline->m_retxCount[3], 1);
466
467 // receive segment 3
468 face.receive(*makeDataWithSegment(3));
469 advanceClocks(io, time::nanoseconds(1));
470
471 BOOST_CHECK_EQUAL(hasFailed, false);
472}
473
474BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterestsAimd
475BOOST_AUTO_TEST_SUITE_END() // Chunks
476
477} // namespace tests
478} // namespace aimd
479} // namespace chunks
480} // namespace ndn