blob: fc533433b83377fd6d1c8ee03c913fd1e9ed656d [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 Pesavento66777622020-10-09 18:46:03 -04003 * Copyright (c) 2016-2020, 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
32namespace ndn {
33namespace chunks {
Weiwei Liu245d7912016-07-28 00:04:25 -070034namespace tests {
35
36using namespace ndn::tests;
37
Klaus Schneider9e5122b2019-03-19 17:03:25 -070038class PipelineInterestCubicFixture : public PipelineInterestsFixture
Weiwei Liu245d7912016-07-28 00:04:25 -070039{
40public:
Klaus Schneider9e5122b2019-03-19 17:03:25 -070041 PipelineInterestCubicFixture()
Davide Pesavento97a33b22019-10-17 22:10:47 -040042 : rttEstimator(makeRttEstimatorOptions())
Weiwei Liu245d7912016-07-28 00:04:25 -070043 {
Davide Pesavento97a33b22019-10-17 22:10:47 -040044 opt.isQuiet = true;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000045 createPipeline();
46 }
47
48 void
49 createPipeline()
50 {
Klaus Schneider9e5122b2019-03-19 17:03:25 -070051 auto pline = make_unique<PipelineInterestsCubic>(face, rttEstimator, opt);
schneiderklausd8197df2019-03-16 11:31:40 -070052 pipeline = pline.get();
Weiwei Liu245d7912016-07-28 00:04:25 -070053 setPipeline(std::move(pline));
54 }
55
56private:
Davide Pesavento5e3773d2019-08-22 15:35:08 -040057 static shared_ptr<RttEstimatorWithStats::Options>
Weiwei Liu245d7912016-07-28 00:04:25 -070058 makeRttEstimatorOptions()
59 {
Davide Pesavento5e3773d2019-08-22 15:35:08 -040060 auto rttOptions = make_shared<RttEstimatorWithStats::Options>();
61 rttOptions->alpha = 0.125;
62 rttOptions->beta = 0.25;
63 rttOptions->k = 8;
64 rttOptions->initialRto = 1_s;
65 rttOptions->minRto = 200_ms;
66 rttOptions->maxRto = 4_s;
67 rttOptions->rtoBackoffMultiplier = 2;
Weiwei Liu245d7912016-07-28 00:04:25 -070068 return rttOptions;
69 }
70
71protected:
Davide Pesavento97a33b22019-10-17 22:10:47 -040072 Options opt;
Davide Pesavento5e3773d2019-08-22 15:35:08 -040073 RttEstimatorWithStats rttEstimator;
Klaus Schneider9e5122b2019-03-19 17:03:25 -070074 PipelineInterestsCubic* pipeline;
Davide Pesaventoba560662019-06-26 22:45:44 -040075 static constexpr double MARGIN = 0.001;
Weiwei Liu245d7912016-07-28 00:04:25 -070076};
77
Klaus Schneider9e5122b2019-03-19 17:03:25 -070078constexpr double PipelineInterestCubicFixture::MARGIN;
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +000079
Weiwei Liu245d7912016-07-28 00:04:25 -070080BOOST_AUTO_TEST_SUITE(Chunks)
Klaus Schneider9e5122b2019-03-19 17:03:25 -070081BOOST_FIXTURE_TEST_SUITE(TestPipelineInterestsCubic, PipelineInterestCubicFixture)
Weiwei Liu245d7912016-07-28 00:04:25 -070082
83BOOST_AUTO_TEST_CASE(SlowStart)
84{
85 nDataSegments = 4;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -070086 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -070087
schneiderklausd8197df2019-03-16 11:31:40 -070088 double preCwnd = pipeline->m_cwnd;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -080089 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -040090 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -070091 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -070092
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -080093 for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
Weiwei Liu245d7912016-07-28 00:04:25 -070094 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -040095 advanceClocks(time::nanoseconds(1));
schneiderklausd8197df2019-03-16 11:31:40 -070096 BOOST_CHECK_CLOSE(pipeline->m_cwnd - preCwnd, 1, MARGIN);
97 preCwnd = pipeline->m_cwnd;
Weiwei Liu245d7912016-07-28 00:04:25 -070098 }
Davide Pesaventoe9c69852017-11-04 18:08:37 -040099
100 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments - 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700101}
102
Weiwei Liu245d7912016-07-28 00:04:25 -0700103
104BOOST_AUTO_TEST_CASE(Timeout)
105{
106 nDataSegments = 8;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700107 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Weiwei Liu245d7912016-07-28 00:04:25 -0700108
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800109 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400110 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700111 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700112
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800113 // receive segment 0, 1, and 2
114 for (uint64_t i = 0; i < 3; ++i) {
Weiwei Liu245d7912016-07-28 00:04:25 -0700115 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400116 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700117 }
118
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400119 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 3);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700120 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 5, MARGIN);
121 BOOST_CHECK_EQUAL(face.sentInterests.size(), 8); // request for segment #7 has been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700122
Davide Pesavento66777622020-10-09 18:46:03 -0400123 advanceClocks(time::milliseconds(100));
Weiwei Liu245d7912016-07-28 00:04:25 -0700124
125 // receive segment 4
126 face.receive(*makeDataWithSegment(4));
Davide Pesavento66777622020-10-09 18:46:03 -0400127 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700128
129 // receive segment 5
130 face.receive(*makeDataWithSegment(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400131 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700132
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400133 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700134 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800135 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all the segment requests have been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700136
schneiderklausd8197df2019-03-16 11:31:40 -0700137 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 0);
138 BOOST_CHECK_EQUAL(pipeline->m_nLossDecr, 0);
139 BOOST_CHECK_EQUAL(pipeline->m_nMarkDecr, 0);
140 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 0);
141 BOOST_CHECK_EQUAL(pipeline->m_nSkippedRetx, 0);
142 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 0);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700143
144 // timeout segment 3 & 6
Davide Pesavento66777622020-10-09 18:46:03 -0400145 advanceClocks(time::milliseconds(150));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700146 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 3);
147 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 3);
schneiderklausd8197df2019-03-16 11:31:40 -0700148 BOOST_CHECK_EQUAL(pipeline->m_nLossDecr, 1);
149 BOOST_CHECK_EQUAL(pipeline->m_nSkippedRetx, 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700150
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400151 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700152 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 -0700153 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700154
155 // receive segment 6, retransmit 3
156 face.receive(*makeDataWithSegment(6));
Davide Pesavento66777622020-10-09 18:46:03 -0400157 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700158
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400159 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700160 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // congestion avoidance
schneiderklausd8197df2019-03-16 11:31:40 -0700161 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
162 BOOST_CHECK_EQUAL(pipeline->m_retxCount[3], 1);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700163
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700164 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts, 3);
165 BOOST_CHECK_EQUAL(pipeline->m_nRetransmitted, 3);
schneiderklausd8197df2019-03-16 11:31:40 -0700166 BOOST_CHECK_EQUAL(pipeline->m_nTimeouts,
167 pipeline->m_nRetransmitted + pipeline->m_nSkippedRetx);
schneiderklaus8ff3abd2019-03-12 22:15:12 -0700168
Weiwei Liu245d7912016-07-28 00:04:25 -0700169}
170
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000171BOOST_AUTO_TEST_CASE(CongestionMarksWithCwa)
172{
173 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700174 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000175
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800176 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400177 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700178 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000179
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800180 // receive segments 0 to 4
181 for (uint64_t i = 0; i < 5; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000182 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400183 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000184 }
185
186 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700187 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000188
189 // receive segment 5 with congestion mark
190 face.receive(*makeDataWithSegmentAndCongMark(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400191 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000192
193 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700194 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 -0800195 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000196
197 // receive the last segment with congestion mark
198 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400199 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000200
201 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700202 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 4.9, MARGIN); // conservative window adaption (window size should not decrease)
schneiderklausd8197df2019-03-16 11:31:40 -0700203 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000204
205 // make sure no interest is retransmitted for marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700206 BOOST_CHECK_EQUAL(pipeline->m_retxCount[5], 0);
207 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000208
209 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700210 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000211}
212
213BOOST_AUTO_TEST_CASE(CongestionMarksWithoutCwa)
214{
215 opt.disableCwa = true;
216 createPipeline();
217
218 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700219 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000220
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800221 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400222 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700223 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000224
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800225 // receive segments 0 to 4
226 for (uint64_t i = 0; i < 5; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000227 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400228 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000229 }
230
231 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 5);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700232 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 7.0, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000233
234 // receive segment 5 with congestion mark
235 face.receive(*makeDataWithSegmentAndCongMark(5));
Davide Pesavento66777622020-10-09 18:46:03 -0400236 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000237
238 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700239 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 -0800240 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000241
242 // receive the last segment with congestion mark
243 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400244 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000245
246 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700247 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 3.43, MARGIN); // window size should decrease, as cwa is disabled
schneiderklausd8197df2019-03-16 11:31:40 -0700248 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000249
250 // make sure no interest is retransmitted for marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700251 BOOST_CHECK_EQUAL(pipeline->m_retxCount[5], 0);
252 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000253
254 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700255 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000256}
257
258BOOST_AUTO_TEST_CASE(IgnoreCongestionMarks)
259{
260 opt.ignoreCongMarks = true;
261 createPipeline();
262
263 nDataSegments = 7;
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700264 BOOST_REQUIRE_CLOSE(pipeline->m_cwnd, 2, MARGIN);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000265
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800266 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400267 advanceClocks(time::nanoseconds(1));
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700268 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000269
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800270 // receive segments 0 to 5
271 for (uint64_t i = 0; i < 6; ++i) {
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000272 face.receive(*makeDataWithSegment(i));
Davide Pesavento66777622020-10-09 18:46:03 -0400273 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000274 }
275
276 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 6);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700277 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 8.0, MARGIN);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800278 BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments); // all interests have been sent
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000279
280 // receive the last segment with congestion mark
281 face.receive(*makeDataWithSegmentAndCongMark(nDataSegments - 1));
Davide Pesavento66777622020-10-09 18:46:03 -0400282 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000283
284 BOOST_CHECK_EQUAL(pipeline->m_nReceived, nDataSegments);
Klaus Schneider4a2e89d2019-10-27 10:04:39 -0700285 BOOST_CHECK_CLOSE(pipeline->m_cwnd, 9.0, MARGIN); // window size increases
schneiderklausd8197df2019-03-16 11:31:40 -0700286 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000287
288 // make sure no interest is retransmitted for marked data packet
schneiderklausd8197df2019-03-16 11:31:40 -0700289 BOOST_CHECK_EQUAL(pipeline->m_retxCount[nDataSegments - 1], 0);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000290
291 // check number of received marked data packets
schneiderklausd8197df2019-03-16 11:31:40 -0700292 BOOST_CHECK_EQUAL(pipeline->m_nCongMarks, 1);
Chavoosh Ghasemi641f5932017-11-06 22:45:11 +0000293}
294
Weiwei Liu245d7912016-07-28 00:04:25 -0700295BOOST_AUTO_TEST_CASE(Nack)
296{
297 nDataSegments = 5;
schneiderklausd8197df2019-03-16 11:31:40 -0700298 pipeline->m_cwnd = 10.0;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800299 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400300 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800301
302 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400303 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700304
305 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400306 advanceClocks(time::nanoseconds(1));
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400307
308 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800309 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 10);
Weiwei Liu245d7912016-07-28 00:04:25 -0700310
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800311 // receive a nack with NackReason::DUPLICATE for segment 1
Weiwei Liu245d7912016-07-28 00:04:25 -0700312 auto nack1 = makeNack(face.sentInterests[1], lp::NackReason::DUPLICATE);
313 face.receive(nack1);
Davide Pesavento66777622020-10-09 18:46:03 -0400314 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700315
316 // nack1 is ignored
317 BOOST_CHECK_EQUAL(hasFailed, false);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400318 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
schneiderklausd8197df2019-03-16 11:31:40 -0700319 BOOST_CHECK_EQUAL(pipeline->m_retxQueue.size(), 0);
Weiwei Liu245d7912016-07-28 00:04:25 -0700320
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800321 // receive a nack with NackReason::CONGESTION for segment 2
Weiwei Liu245d7912016-07-28 00:04:25 -0700322 auto nack2 = makeNack(face.sentInterests[2], lp::NackReason::CONGESTION);
323 face.receive(nack2);
Davide Pesavento66777622020-10-09 18:46:03 -0400324 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700325
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800326 // segment 2 is retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700327 BOOST_CHECK_EQUAL(pipeline->m_retxCount[2], 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700328
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800329 // receive a nack with NackReason::NONE for segment 3
Weiwei Liu245d7912016-07-28 00:04:25 -0700330 auto nack3 = makeNack(face.sentInterests[3], lp::NackReason::NONE);
331 face.receive(nack3);
Davide Pesavento66777622020-10-09 18:46:03 -0400332 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700333
334 // Other types of Nack will trigger a failure
335 BOOST_CHECK_EQUAL(hasFailed, true);
Davide Pesaventoe9c69852017-11-04 18:08:37 -0400336 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700337}
338
339BOOST_AUTO_TEST_CASE(FinalBlockIdNotSetAtBeginning)
340{
341 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700342 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800343 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400344 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700345
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800346 // receive segment 0 without FinalBlockId
347 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400348 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700349
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800350 // interests for segment 0 - 5 have been sent
Weiwei Liu245d7912016-07-28 00:04:25 -0700351 BOOST_CHECK_EQUAL(face.sentInterests.size(), 6);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800352 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 1);
schneiderklausd8197df2019-03-16 11:31:40 -0700353 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, false);
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800354 // pending interests: segment 1, 2, 3, 4, 5
Weiwei Liu245d7912016-07-28 00:04:25 -0700355 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 5);
356
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800357 // receive segment 1 with FinalBlockId
358 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400359 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800360 BOOST_CHECK_EQUAL(pipeline->m_nReceived, 2);
schneiderklausd8197df2019-03-16 11:31:40 -0700361 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, true);
Weiwei Liu245d7912016-07-28 00:04:25 -0700362
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800363 // pending interests for segment 1, 4, 5 haven been removed
364 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 2);
Weiwei Liu245d7912016-07-28 00:04:25 -0700365}
366
367BOOST_AUTO_TEST_CASE(FailureBeforeFinalBlockIdReceived)
368{
369 // failed to retrieve segNo while the FinalBlockId has not yet been
370 // set, and later received a FinalBlockId >= segNo, i.e. segNo is
371 // part of the content.
372
373 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700374 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800375 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400376 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800377
378 // receive segment 0 without FinalBlockId
379 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400380 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700381
382 // receive segment 1 without FinalBlockId
383 face.receive(*makeDataWithSegment(1, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400384 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800385
386 // interests for segment 0 - 7 have been sent
387 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 8);
Weiwei Liu245d7912016-07-28 00:04:25 -0700388
389 // receive nack with NackReason::NONE for segment 3
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800390 auto nack = makeNack(face.sentInterests[3], lp::NackReason::NONE);
Weiwei Liu245d7912016-07-28 00:04:25 -0700391 face.receive(nack);
Davide Pesavento66777622020-10-09 18:46:03 -0400392 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700393
394 // error not triggered
395 // pending interests for segment > 3 haven been removed
396 BOOST_CHECK_EQUAL(hasFailed, false);
397 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
398
399 // receive segment 2 with FinalBlockId
400 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400401 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700402
403 // error triggered since segment 3 is part of the content
404 BOOST_CHECK_EQUAL(hasFailed, true);
405}
406
407BOOST_AUTO_TEST_CASE(SpuriousFailureBeforeFinalBlockIdReceived)
408{
409 // failed to retrieve segNo while the FinalBlockId has not yet been
410 // set, and later received a FinalBlockId < segNo, i.e. segNo is
411 // not part of the content, and it was actually a spurious failure
412
413 nDataSegments = 4;
schneiderklausd8197df2019-03-16 11:31:40 -0700414 pipeline->m_cwnd = 4;
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800415 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400416 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800417
418 // receive segment 0 without FinalBlockId
419 face.receive(*makeDataWithSegment(0, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400420 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700421
422 // receive segment 1 without FinalBlockId
423 face.receive(*makeDataWithSegment(1, false));
Davide Pesavento66777622020-10-09 18:46:03 -0400424 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800425
426 // interests for segment 0 - 7 have been sent
427 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 8);
Weiwei Liu245d7912016-07-28 00:04:25 -0700428
429 // receive nack with NackReason::NONE for segment 4
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800430 auto nack = makeNack(face.sentInterests[4], lp::NackReason::NONE);
Weiwei Liu245d7912016-07-28 00:04:25 -0700431 face.receive(nack);
Davide Pesavento66777622020-10-09 18:46:03 -0400432 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700433
434 // error not triggered
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800435 // pending interests for segment > 3 have been removed
Weiwei Liu245d7912016-07-28 00:04:25 -0700436 BOOST_CHECK_EQUAL(hasFailed, false);
437 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 2);
438
439 // receive segment 2 with FinalBlockId
440 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400441 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700442
443 // timeout segment 3
Davide Pesavento66777622020-10-09 18:46:03 -0400444 advanceClocks(time::seconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700445
446 // segment 3 is retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700447 BOOST_CHECK_EQUAL(pipeline->m_retxCount[3], 1);
Weiwei Liu245d7912016-07-28 00:04:25 -0700448
449 // receive segment 3
450 face.receive(*makeDataWithSegment(3));
Davide Pesavento66777622020-10-09 18:46:03 -0400451 advanceClocks(time::nanoseconds(1));
Weiwei Liu245d7912016-07-28 00:04:25 -0700452
453 BOOST_CHECK_EQUAL(hasFailed, false);
454}
455
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500456BOOST_AUTO_TEST_CASE(SegmentInfoMaintenance)
457{
458 // test that m_segmentInfo is properly maintained when
459 // a segment is received after two consecutive timeouts
460
461 nDataSegments = 3;
462
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800463 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400464 advanceClocks(time::nanoseconds(1));
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800465
466 // receive segment 0
467 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400468 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500469
470 // receive segment 1
471 face.receive(*makeDataWithSegment(1));
Davide Pesavento66777622020-10-09 18:46:03 -0400472 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500473
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800474 BOOST_CHECK_EQUAL(face.sentInterests.size(), 3);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500475
476 // check if segment 2's state is FirstTimeSent
schneiderklausd8197df2019-03-16 11:31:40 -0700477 auto it = pipeline->m_segmentInfo.find(2);
478 BOOST_REQUIRE(it != pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500479 BOOST_CHECK(it->second.state == SegmentState::FirstTimeSent);
480
481 // timeout segment 2 twice
Davide Pesavento66777622020-10-09 18:46:03 -0400482 advanceClocks(time::milliseconds(400), 3);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500483
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800484 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500485
486 // check if segment 2's state is Retransmitted
schneiderklausd8197df2019-03-16 11:31:40 -0700487 it = pipeline->m_segmentInfo.find(2);
488 BOOST_REQUIRE(it != pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500489 BOOST_CHECK(it->second.state == SegmentState::Retransmitted);
490
491 // check if segment 2 was retransmitted twice
schneiderklausd8197df2019-03-16 11:31:40 -0700492 BOOST_CHECK_EQUAL(pipeline->m_retxCount.at(2), 2);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500493
494 // receive segment 2 the first time
495 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400496 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500497
498 // check if segment 2 was erased from m_segmentInfo
schneiderklausd8197df2019-03-16 11:31:40 -0700499 it = pipeline->m_segmentInfo.find(2);
500 BOOST_CHECK(it == pipeline->m_segmentInfo.end());
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500501
502 auto prevRtt = rttEstimator.getAvgRtt();
503 auto prevRto = rttEstimator.getEstimatedRto();
504
505 // receive segment 2 the second time
506 face.receive(*makeDataWithSegment(2));
Davide Pesavento66777622020-10-09 18:46:03 -0400507 advanceClocks(time::nanoseconds(1));
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500508
509 // nothing changed
schneiderklausd8197df2019-03-16 11:31:40 -0700510 it = pipeline->m_segmentInfo.find(2);
511 BOOST_CHECK(it == pipeline->m_segmentInfo.end());
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800512 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
Ryan Wickman2c9933c2018-06-12 11:51:51 -0500513 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt(), prevRtt);
514 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), prevRto);
515}
516
Chavoosh Ghasemi75309ae2018-03-26 14:46:24 -0400517BOOST_AUTO_TEST_CASE(PrintSummaryWithNoRttMeasurements)
518{
519 // test the console ouptut when no RTT measurement is available,
520 // to make sure a proper message will be printed out
521
522 std::stringstream ss;
523
524 // change the underlying buffer and save the old buffer
525 auto oldBuf = std::cerr.rdbuf(ss.rdbuf());
526
schneiderklausd8197df2019-03-16 11:31:40 -0700527 pipeline->printSummary();
Chavoosh Ghasemi75309ae2018-03-26 14:46:24 -0400528 std::string line;
529
530 bool found = false;
531 while (std::getline(ss, line)) {
532 if (line == "RTT stats unavailable") {
533 found = true;
534 break;
535 }
536 }
537 BOOST_CHECK(found);
538 std::cerr.rdbuf(oldBuf); // reset
539}
540
Ryan Wickman034f30f2018-06-06 11:11:11 -0500541BOOST_AUTO_TEST_CASE(StopsWhenFileSizeLessThanChunkSize)
542{
543 // test to see if the program doesn't hang,
544 // when transfer is complete, for files less than the chunk size
545 // (i.e. when only one segment is sent/received)
546
547 createPipeline();
548 nDataSegments = 1;
549
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800550 run(name);
Davide Pesavento66777622020-10-09 18:46:03 -0400551 advanceClocks(time::nanoseconds(1));
Ryan Wickman034f30f2018-06-06 11:11:11 -0500552
Chavoosh Ghasemi5cb67012019-02-15 09:56:57 -0800553 face.receive(*makeDataWithSegment(0));
Davide Pesavento66777622020-10-09 18:46:03 -0400554 advanceClocks(time::nanoseconds(1));
Ryan Wickman034f30f2018-06-06 11:11:11 -0500555
schneiderklausd8197df2019-03-16 11:31:40 -0700556 BOOST_CHECK_EQUAL(pipeline->m_hasFinalBlockId, true);
557 BOOST_CHECK_EQUAL(pipeline->m_segmentInfo.size(), 0);
Ryan Wickman034f30f2018-06-06 11:11:11 -0500558 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
559}
560
561
Klaus Schneider9e5122b2019-03-19 17:03:25 -0700562BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterestsCubic
Weiwei Liu245d7912016-07-28 00:04:25 -0700563BOOST_AUTO_TEST_SUITE_END() // Chunks
564
565} // namespace tests
Weiwei Liu245d7912016-07-28 00:04:25 -0700566} // namespace chunks
567} // namespace ndn