blob: 9934d9f04f1d3b8da2416af27455709f80bbcddc [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 Pesaventob3570c62022-02-19 19:19:00 -05003 * Copyright (c) 2016-2022, Regents of the University of California,
Davide Pesavento958896e2017-01-19 00:52:04 -05004 * 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
schneiderklausd8197df2019-03-16 11:31:40 -070025 * @author Klaus Schneider
Weiwei Liu245d7912016-07-28 00:04:25 -070026 */
27
Klaus Schneider9e5122b2019-03-19 17:03:25 -070028#include "tools/chunks/catchunks/pipeline-interests-cubic.hpp"
Weiwei Liu245d7912016-07-28 00:04:25 -070029
30#include "pipeline-interests-fixture.hpp"
31
Davide Pesaventob3570c62022-02-19 19:19:00 -050032namespace ndn::chunks::tests {
Weiwei Liu245d7912016-07-28 00:04:25 -070033
34using namespace ndn::tests;
35
Klaus Schneider9e5122b2019-03-19 17:03:25 -070036class PipelineInterestCubicFixture : public PipelineInterestsFixture
Weiwei Liu245d7912016-07-28 00:04:25 -070037{
Davide Pesaventob3570c62022-02-19 19:19:00 -050038protected:
Klaus Schneider9e5122b2019-03-19 17:03:25 -070039 PipelineInterestCubicFixture()
Weiwei Liu245d7912016-07-28 00:04:25 -070040 {
Davide Pesavento97a33b22019-10-17 22:10:47 -040041 opt.isQuiet = true;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000042 createPipeline();
43 }
44
45 void
46 createPipeline()
47 {
Klaus Schneider9e5122b2019-03-19 17:03:25 -070048 auto pline = make_unique<PipelineInterestsCubic>(face, rttEstimator, opt);
schneiderklausd8197df2019-03-16 11:31:40 -070049 pipeline = pline.get();
Weiwei Liu245d7912016-07-28 00:04:25 -070050 setPipeline(std::move(pline));
51 }
52
53private:
Davide Pesavento5e3773d2019-08-22 15:35:08 -040054 static shared_ptr<RttEstimatorWithStats::Options>
Weiwei Liu245d7912016-07-28 00:04:25 -070055 makeRttEstimatorOptions()
56 {
Davide Pesavento5e3773d2019-08-22 15:35:08 -040057 auto rttOptions = make_shared<RttEstimatorWithStats::Options>();
58 rttOptions->alpha = 0.125;
59 rttOptions->beta = 0.25;
60 rttOptions->k = 8;
61 rttOptions->initialRto = 1_s;
62 rttOptions->minRto = 200_ms;
63 rttOptions->maxRto = 4_s;
64 rttOptions->rtoBackoffMultiplier = 2;
Weiwei Liu245d7912016-07-28 00:04:25 -070065 return rttOptions;
66 }
67
68protected:
Davide Pesavento97a33b22019-10-17 22:10:47 -040069 Options opt;
Davide Pesaventob3570c62022-02-19 19:19:00 -050070 RttEstimatorWithStats rttEstimator{makeRttEstimatorOptions()};
Klaus Schneider9e5122b2019-03-19 17:03:25 -070071 PipelineInterestsCubic* pipeline;
Davide Pesaventoba560662019-06-26 22:45:44 -040072 static constexpr double MARGIN = 0.001;
Weiwei Liu245d7912016-07-28 00:04:25 -070073};
74
Klaus Schneider9e5122b2019-03-19 17:03:25 -070075constexpr double PipelineInterestCubicFixture::MARGIN;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000076
Weiwei Liu245d7912016-07-28 00:04:25 -070077BOOST_AUTO_TEST_SUITE(Chunks)
Klaus Schneider9e5122b2019-03-19 17:03:25 -070078BOOST_FIXTURE_TEST_SUITE(TestPipelineInterestsCubic, PipelineInterestCubicFixture)
Weiwei Liu245d7912016-07-28 00:04:25 -070079
80BOOST_AUTO_TEST_CASE(SlowStart)
81{
82 nDataSegments = 4;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -070083 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -070084
schneiderklausd8197df2019-03-16 11:31:40 -070085 double preCwnd = pipeline->m_cwnd;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -080086 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -040087 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -070088 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -070089
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -080090 for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
Weiwei Liu245d7912016-07-28 00:04:25 -070091 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -040092 advanceClocks(time::nanoseconds(1));
schneiderklausd8197df2019-03-16 11:31:40 -070093 BOOST_CHECK_CLOSE(pipeline->m_cwnd - preCwnd, 1, MARGIN);
94 preCwnd = pipeline->m_cwnd;
Weiwei Liu245d7912016-07-28 00:04:25 -070095 }
Davide Pesaventoe9c69852017-11-04 18:08:37 -040096
97 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments - 1);
Weiwei Liu245d7912016-07-28 00:04:25 -070098}
99
Weiwei Liu245d7912016-07-28 00:04:25 -0700100
101BOOST_AUTO_TEST_CASE(Timeout)
102{
103 nDataSegments = 8;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700104 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700105
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800106 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400107 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700108 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700109
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800110 // receive segment 0, 1, and 2
111 for (uint64_t i = 0; i < 3; ++i) {
Weiwei Liu245d7912016-07-28 00:04:25 -0700112 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400113 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700114 }
115
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400116 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 3);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700117 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 5, MARGIN);
118 BOOST_CHECK_EQUAL(face.sentInterests.size(), 8); // request for segment #7 has been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700119
Davide Pesavento66777622020-10-09 18:46:03 -0400120 advanceClocks(time::milliseconds(100));
Weiwei Liu245d7912016-07-28 00:04:25 -0700121
122 // receive segment 4
123 face.receive(*makeDataWithSegment(4));
Davide Pesavento66777622020-10-09 18:46:03 -0400124 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700125
126 // receive segment 5
127 face.receive(*makeDataWithSegment(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400128 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700129
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400130 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700131 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800132 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all the segment requests have been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700133
schneiderklausd8197df2019-03-16 11:31:40 -0700134 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 0);
135 BOOST_CHECK_EQUAL(pipeline->m_nLossDecr, 0);
136 BOOST_CHECK_EQUAL(pipeline->m_nMarkDecr, 0);
137 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 0);
138 BOOST_CHECK_EQUAL(pipeline->m_nSkippedRetx, 0);
139 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 0);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700140
141 // timeout segment 3 & 6
Davide Pesavento66777622020-10-09 18:46:03 -0400142 advanceClocks(time::milliseconds(150));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700143 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 3);
144 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 3);
schneiderklausd8197df2019-03-16 11:31:40 -0700145 BOOST_CHECK_EQUAL(pipeline->m_nLossDecr, 1);
146 BOOST_CHECK_EQUAL(pipeline->m_nSkippedRetx, 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700147
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400148 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700149 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // window size drop to 0.7x of previous size
Klaus Schneider9e5122b2019-03-19 17:03:25 -0700150 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700151
152 // receive segment 6, retransmit 3
153 face.receive(*makeDataWithSegment(6));
Davide Pesavento66777622020-10-09 18:46:03 -0400154 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700155
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400156 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700157 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // congestion avoidance
schneiderklausd8197df2019-03-16 11:31:40 -0700158 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
159 BOOST_CHECK_EQUAL(pipeline->m_retxCount[3], 1);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700160
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700161 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 3);
162 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 3);
schneiderklausd8197df2019-03-16 11:31:40 -0700163 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts,
164 pipeline->m_nRetransmitted + pipeline->m_nSkippedRetx);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700165
Weiwei Liu245d7912016-07-28 00:04:25 -0700166}
167
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000168BOOST_AUTO_TEST_CASE(CongestionMarksWithCwa)
169{
170 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700171 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000172
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800173 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400174 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700175 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000176
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800177 // receive segments 0 to 4
178 for (uint64_t i = 0; i < 5; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000179 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400180 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000181 }
182
183 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700184 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000185
186 // receive segment 5 with congestion mark
187 face.receive(*makeDataWithSegmentAndCongMark(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400188 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000189
190 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700191 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // window size drops to 0.7x of previous size
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800192 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000193
194 // receive the last segment with congestion mark
195 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400196 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000197
198 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700199 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // conservative window adaption (window size should not decrease)
schneiderklausd8197df2019-03-16 11:31:40 -0700200 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000201
202 // make sure no interest is retransmitted for marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700203 BOOST_CHECK_EQUAL(pipeline->m_retxCount[5], 0);
204 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000205
206 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700207 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000208}
209
210BOOST_AUTO_TEST_CASE(CongestionMarksWithoutCwa)
211{
212 opt.disableCwa = true;
213 createPipeline();
214
215 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700216 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000217
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800218 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400219 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700220 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000221
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800222 // receive segments 0 to 4
223 for (uint64_t i = 0; i < 5; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000224 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400225 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000226 }
227
228 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700229 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000230
231 // receive segment 5 with congestion mark
232 face.receive(*makeDataWithSegmentAndCongMark(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400233 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000234
235 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700236 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // window size drops to 0.7x of previous size
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800237 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000238
239 // receive the last segment with congestion mark
240 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400241 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000242
243 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700244 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 3.43, MARGIN); // window size should decrease, as cwa is disabled
schneiderklausd8197df2019-03-16 11:31:40 -0700245 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000246
247 // make sure no interest is retransmitted for marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700248 BOOST_CHECK_EQUAL(pipeline->m_retxCount[5], 0);
249 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000250
251 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700252 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000253}
254
255BOOST_AUTO_TEST_CASE(IgnoreCongestionMarks)
256{
257 opt.ignoreCongMarks = true;
258 createPipeline();
259
260 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700261 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000262
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800263 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400264 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700265 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000266
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800267 // receive segments 0 to 5
268 for (uint64_t i = 0; i < 6; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000269 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400270 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000271 }
272
273 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700274 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 8.0, MARGIN);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800275 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000276
277 // receive the last segment with congestion mark
278 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400279 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000280
281 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700282 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 9.0, MARGIN); // window size increases
schneiderklausd8197df2019-03-16 11:31:40 -0700283 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000284
285 // make sure no interest is retransmitted for marked data packet
schneiderklausd8197df2019-03-16 11:31:40 -0700286 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000287
288 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700289 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 1);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000290}
291
Weiwei Liu245d7912016-07-28 00:04:25 -0700292BOOST_AUTO_TEST_CASE(Nack)
293{
294 nDataSegments = 5;
schneiderklausd8197df2019-03-16 11:31:40 -0700295 pipeline->m_cwnd = 10.0;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800296 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400297 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800298
299 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400300 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700301
302 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400303 advanceClocks(time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400304
305 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800306 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 10);
Weiwei Liu245d7912016-07-28 00:04:25 -0700307
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800308 // receive a nack with NackReason::DUPLICATE for segment 1
Weiwei Liu245d7912016-07-28 00:04:25 -0700309 auto nack1 = makeNack(face.sentInterests[1], lp::NackReason::DUPLICATE);
310 face.receive(nack1);
Davide Pesavento66777622020-10-09 18:46:03 -0400311 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700312
313 // nack1 is ignored
314 BOOST_CHECK_EQUAL(hasFailed, false);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400315 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
schneiderklausd8197df2019-03-16 11:31:40 -0700316 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700317
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800318 // receive a nack with NackReason::CONGESTION for segment 2
Weiwei Liu245d7912016-07-28 00:04:25 -0700319 auto nack2 = makeNack(face.sentInterests[2], lp::NackReason::CONGESTION);
320 face.receive(nack2);
Davide Pesavento66777622020-10-09 18:46:03 -0400321 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700322
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800323 // segment 2 is retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700324 BOOST_CHECK_EQUAL(pipeline->m_retxCount[2], 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700325
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800326 // receive a nack with NackReason::NONE for segment 3
Weiwei Liu245d7912016-07-28 00:04:25 -0700327 auto nack3 = makeNack(face.sentInterests[3], lp::NackReason::NONE);
328 face.receive(nack3);
Davide Pesavento66777622020-10-09 18:46:03 -0400329 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700330
331 // Other types of Nack will trigger a failure
332 BOOST_CHECK_EQUAL(hasFailed, true);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400333 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700334}
335
336BOOST_AUTO_TEST_CASE(FinalBlockIdNotSetAtBeginning)
337{
338 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700339 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800340 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400341 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700342
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800343 // receive segment 0 without FinalBlockId
344 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400345 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700346
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800347 // interests for segment 0 - 5 have been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700348 BOOST_CHECK_EQUAL(face.sentInterests.size(), 6);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800349 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 1);
schneiderklausd8197df2019-03-16 11:31:40 -0700350 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, false);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800351 // pending interests: segment 1, 2, 3, 4, 5
Weiwei Liu245d7912016-07-28 00:04:25 -0700352 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 5);
353
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800354 // receive segment 1 with FinalBlockId
355 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400356 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800357 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
schneiderklausd8197df2019-03-16 11:31:40 -0700358 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, true);
Weiwei Liu245d7912016-07-28 00:04:25 -0700359
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800360 // pending interests for segment 1, 4, 5 haven been removed
361 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700362}
363
364BOOST_AUTO_TEST_CASE(FailureBeforeFinalBlockIdReceived)
365{
366 // failed to retrieve segNo while the FinalBlockId has not yet been
367 // set, and later received a FinalBlockId >= segNo, i.e. segNo is
368 // part of the content.
369
370 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700371 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800372 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400373 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800374
375 // receive segment 0 without FinalBlockId
376 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400377 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700378
379 // receive segment 1 without FinalBlockId
380 face.receive(*makeDataWithSegment(1, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400381 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800382
383 // interests for segment 0 - 7 have been sent
384 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 8);
Weiwei Liu245d7912016-07-28 00:04:25 -0700385
386 // receive nack with NackReason::NONE for segment 3
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800387 auto nack = makeNack(face.sentInterests[3], lp::NackReason::NONE);
Weiwei Liu245d7912016-07-28 00:04:25 -0700388 face.receive(nack);
Davide Pesavento66777622020-10-09 18:46:03 -0400389 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700390
391 // error not triggered
392 // pending interests for segment > 3 haven been removed
393 BOOST_CHECK_EQUAL(hasFailed, false);
394 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
395
396 // receive segment 2 with FinalBlockId
397 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400398 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700399
400 // error triggered since segment 3 is part of the content
401 BOOST_CHECK_EQUAL(hasFailed, true);
402}
403
404BOOST_AUTO_TEST_CASE(SpuriousFailureBeforeFinalBlockIdReceived)
405{
406 // failed to retrieve segNo while the FinalBlockId has not yet been
407 // set, and later received a FinalBlockId < segNo, i.e. segNo is
408 // not part of the content, and it was actually a spurious failure
409
410 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700411 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800412 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400413 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800414
415 // receive segment 0 without FinalBlockId
416 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400417 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700418
419 // receive segment 1 without FinalBlockId
420 face.receive(*makeDataWithSegment(1, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400421 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800422
423 // interests for segment 0 - 7 have been sent
424 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 8);
Weiwei Liu245d7912016-07-28 00:04:25 -0700425
426 // receive nack with NackReason::NONE for segment 4
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800427 auto nack = makeNack(face.sentInterests[4], lp::NackReason::NONE);
Weiwei Liu245d7912016-07-28 00:04:25 -0700428 face.receive(nack);
Davide Pesavento66777622020-10-09 18:46:03 -0400429 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700430
431 // error not triggered
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800432 // pending interests for segment > 3 have been removed
Weiwei Liu245d7912016-07-28 00:04:25 -0700433 BOOST_CHECK_EQUAL(hasFailed, false);
434 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 2);
435
436 // receive segment 2 with FinalBlockId
437 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400438 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700439
440 // timeout segment 3
Davide Pesavento66777622020-10-09 18:46:03 -0400441 advanceClocks(time::seconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700442
443 // segment 3 is retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700444 BOOST_CHECK_EQUAL(pipeline->m_retxCount[3], 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700445
446 // receive segment 3
447 face.receive(*makeDataWithSegment(3));
Davide Pesavento66777622020-10-09 18:46:03 -0400448 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700449
450 BOOST_CHECK_EQUAL(hasFailed, false);
451}
452
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500453BOOST_AUTO_TEST_CASE(SegmentInfoMaintenance)
454{
455 // test that m_segmentInfo is properly maintained when
456 // a segment is received after two consecutive timeouts
457
458 nDataSegments = 3;
459
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800460 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400461 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800462
463 // receive segment 0
464 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400465 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500466
467 // receive segment 1
468 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400469 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500470
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800471 BOOST_CHECK_EQUAL(face.sentInterests.size(), 3);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500472
473 // check if segment 2's state is FirstTimeSent
schneiderklausd8197df2019-03-16 11:31:40 -0700474 auto it = pipeline->m_segmentInfo.find(2);
475 BOOST_REQUIRE(it != pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500476 BOOST_CHECK(it->second.state == SegmentState::FirstTimeSent);
477
478 // timeout segment 2 twice
Davide Pesavento66777622020-10-09 18:46:03 -0400479 advanceClocks(time::milliseconds(400), 3);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500480
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800481 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500482
483 // check if segment 2's state is Retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700484 it = pipeline->m_segmentInfo.find(2);
485 BOOST_REQUIRE(it != pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500486 BOOST_CHECK(it->second.state == SegmentState::Retransmitted);
487
488 // check if segment 2 was retransmitted twice
schneiderklausd8197df2019-03-16 11:31:40 -0700489 BOOST_CHECK_EQUAL(pipeline->m_retxCount.at(2), 2);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500490
491 // receive segment 2 the first time
492 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400493 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500494
495 // check if segment 2 was erased from m_segmentInfo
schneiderklausd8197df2019-03-16 11:31:40 -0700496 it = pipeline->m_segmentInfo.find(2);
497 BOOST_CHECK(it == pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500498
499 auto prevRtt = rttEstimator.getAvgRtt();
500 auto prevRto = rttEstimator.getEstimatedRto();
501
502 // receive segment 2 the second time
503 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400504 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500505
506 // nothing changed
schneiderklausd8197df2019-03-16 11:31:40 -0700507 it = pipeline->m_segmentInfo.find(2);
508 BOOST_CHECK(it == pipeline->m_segmentInfo.end());
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800509 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500510 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt(), prevRtt);
511 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), prevRto);
512}
513
Chavoosh Ghasemi75309ae2018-03-26 14:46:24 -0400514BOOST_AUTO_TEST_CASE(PrintSummaryWithNoRttMeasurements)
515{
516 // test the console ouptut when no RTT measurement is available,
517 // to make sure a proper message will be printed out
518
519 std::stringstream ss;
520
521 // change the underlying buffer and save the old buffer
522 auto oldBuf = std::cerr.rdbuf(ss.rdbuf());
523
schneiderklausd8197df2019-03-16 11:31:40 -0700524 pipeline->printSummary();
Chavoosh Ghasemi75309ae2018-03-26 14:46:24 -0400525 std::string line;
526
527 bool found = false;
528 while (std::getline(ss, line)) {
529 if (line == "RTT stats unavailable") {
530 found = true;
531 break;
532 }
533 }
534 BOOST_CHECK(found);
535 std::cerr.rdbuf(oldBuf); // reset
536}
537
Ryan Wickman034f30f2018-06-06 11:11:11 -0500538BOOST_AUTO_TEST_CASE(StopsWhenFileSizeLessThanChunkSize)
539{
540 // test to see if the program doesn't hang,
541 // when transfer is complete, for files less than the chunk size
542 // (i.e. when only one segment is sent/received)
543
544 createPipeline();
545 nDataSegments = 1;
546
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800547 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400548 advanceClocks(time::nanoseconds(1));
Ryan Wickman034f30f2018-06-06 11:11:11 -0500549
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800550 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400551 advanceClocks(time::nanoseconds(1));
Ryan Wickman034f30f2018-06-06 11:11:11 -0500552
schneiderklausd8197df2019-03-16 11:31:40 -0700553 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, true);
554 BOOST_CHECK_EQUAL(pipeline->m_segmentInfo.size(), 0);
Ryan Wickman034f30f2018-06-06 11:11:11 -0500555 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
556}
557
558
Klaus Schneider9e5122b2019-03-19 17:03:25 -0700559BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterestsCubic
Weiwei Liu245d7912016-07-28 00:04:25 -0700560BOOST_AUTO_TEST_SUITE_END() // Chunks
561
Davide Pesaventob3570c62022-02-19 19:19:00 -0500562} // namespace ndn::chunks::tests