blob: 34afd03eab843232c46d5806b3b44f11562c8108 [file] [log] [blame]
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -08002/*
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +00003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "util/segment-fetcher.hpp"
Davide Pesavento5d0b0102017-10-07 13:43:16 -040023
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050024#include "data.hpp"
Davide Pesavento5d0b0102017-10-07 13:43:16 -040025#include "lp/nack.hpp"
Junxiao Shi2bea5c42017-08-14 20:10:32 +000026#include "util/dummy-client-face.hpp"
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070027
28#include "boost-test.hpp"
Junxiao Shi2bea5c42017-08-14 20:10:32 +000029#include "dummy-validator.hpp"
30#include "make-interest-data.hpp"
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070031#include "../identity-management-time-fixture.hpp"
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070032
Eric Newberrye345baa2018-05-23 18:17:07 -070033#include <set>
34
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070035namespace ndn {
36namespace util {
37namespace tests {
38
Junxiao Shi0f3f0b42016-07-14 13:26:37 +000039using namespace ndn::tests;
40
Alexander Afanasyev80782e02017-01-04 13:16:54 -080041class Fixture : public IdentityManagementTimeFixture
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070042{
43public:
44 Fixture()
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070045 : face(io, m_keyChain)
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070046 {
47 }
48
Davide Pesavento5d0b0102017-10-07 13:43:16 -040049 static shared_ptr<Data>
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050050 makeDataSegment(const Name& baseName, uint64_t segment, bool isFinal)
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070051 {
52 const uint8_t buffer[] = "Hello, world!";
53
Junxiao Shid5827ce2016-07-14 20:49:37 +000054 auto data = make_shared<Data>(Name(baseName).appendSegment(segment));
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070055 data->setContent(buffer, sizeof(buffer));
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050056 if (isFinal) {
Junxiao Shiebfe4a22018-04-01 23:53:40 +000057 data->setFinalBlock(data->getName()[-1]);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050058 }
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070059
Davide Pesavento5d0b0102017-10-07 13:43:16 -040060 return signData(data);
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070061 }
62
63 void
64 onError(uint32_t errorCode)
65 {
66 ++nErrors;
67 lastError = errorCode;
68 }
69
70 void
Eric Newberrye345baa2018-05-23 18:17:07 -070071 onComplete(ConstBufferPtr data)
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070072 {
Eric Newberrycc910cd2018-05-06 17:01:40 -070073 ++nCompletions;
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070074 dataSize = data->size();
Eric Newberrye345baa2018-05-23 18:17:07 -070075 dataBuf = data;
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070076 }
77
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050078 void
79 nackLastInterest(lp::NackReason nackReason)
80 {
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080081 const Interest& lastInterest = face.sentInterests.back();
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050082 lp::Nack nack = makeNack(lastInterest, nackReason);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080083 face.receive(nack);
Davide Pesavento0f830802018-01-16 23:58:58 -050084 advanceClocks(10_ms);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -050085 }
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -070086
Eric Newberrycc910cd2018-05-06 17:01:40 -070087 void
88 connectSignals(shared_ptr<SegmentFetcher> fetcher)
89 {
90 fetcher->onComplete.connect(bind(&Fixture::onComplete, this, _1));
91 fetcher->onError.connect(bind(&Fixture::onError, this, _1));
92 }
93
Eric Newberrye345baa2018-05-23 18:17:07 -070094 void
95 onInterest(const Interest& interest)
96 {
97 if (interest.getName().get(-1).isSegment()) {
98 if (segmentsToDropOrNack.size() > 0 &&
99 interest.getName().get(-1).toSegment() == segmentsToDropOrNack.front()) {
100 segmentsToDropOrNack.pop();
101 if (sendNackInsteadOfDropping) {
102 lp::Nack nack = makeNack(interest, nackReason);
103 face.receive(nack);
104 }
105 return;
106 }
107
108 auto data = makeDataSegment("/hello/world/version0",
109 interest.getName().get(-1).toSegment(),
110 interest.getName().get(-1).toSegment() == nSegments - 1);
111 face.receive(*data);
112
113 uniqSegmentsSent.insert(interest.getName().get(-1).toSegment());
114 if (uniqSegmentsSent.size() == nSegments) {
115 io.stop();
116 }
117 }
118 else {
119 if (segmentsToDropOrNack.size() > 0 &&
120 segmentsToDropOrNack.front() == 0) {
121 segmentsToDropOrNack.pop();
122 if (sendNackInsteadOfDropping) {
123 lp::Nack nack = makeNack(interest, nackReason);
124 face.receive(nack);
125 }
126 return;
127 }
128
129 auto data = makeDataSegment("/hello/world/version0", defaultSegmentToSend, nSegments == 1);
130 face.receive(*data);
131 uniqSegmentsSent.insert(defaultSegmentToSend);
132 }
133 }
134
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700135public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800136 DummyClientFace face;
Eric Newberrye345baa2018-05-23 18:17:07 -0700137 std::set<uint64_t> uniqSegmentsSent;
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700138
Eric Newberrycc910cd2018-05-06 17:01:40 -0700139 int nErrors = 0;
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400140 uint32_t lastError = 0;
Eric Newberrycc910cd2018-05-06 17:01:40 -0700141 int nCompletions = 0;
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400142 size_t dataSize = 0;
Eric Newberrye345baa2018-05-23 18:17:07 -0700143 ConstBufferPtr dataBuf;
144
145 // number of segments in fetched object
146 uint64_t nSegments = 0;
147 std::queue<uint64_t> segmentsToDropOrNack;
148 bool sendNackInsteadOfDropping = false;
149 lp::NackReason nackReason = lp::NackReason::NONE;
150 // segment that is sent in response to an Interest w/o a segment component in its name
151 uint64_t defaultSegmentToSend = 0;
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700152};
153
Eric Newberrye345baa2018-05-23 18:17:07 -0700154BOOST_AUTO_TEST_SUITE(Util)
155BOOST_FIXTURE_TEST_SUITE(TestSegmentFetcher, Fixture)
156
157BOOST_AUTO_TEST_CASE(InvalidOptions)
158{
159 SegmentFetcher::Options options;
160 options.mdCoef = 1.5;
161 DummyValidator acceptValidator;
162 BOOST_CHECK_THROW(SegmentFetcher::start(face, Interest("/hello/world"), acceptValidator, options),
163 std::invalid_argument);
164}
165
166BOOST_AUTO_TEST_CASE(ExceedMaxTimeout)
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700167{
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -0800168 DummyValidator acceptValidator;
Eric Newberrye345baa2018-05-23 18:17:07 -0700169 size_t nAfterSegmentTimedOut = 0;
170 SegmentFetcher::Options options;
171 options.maxTimeout = 100_ms;
172 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
173 acceptValidator, options);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700174 connectSignals(fetcher);
Eric Newberrye345baa2018-05-23 18:17:07 -0700175 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700176
Davide Pesavento0f830802018-01-16 23:58:58 -0500177 advanceClocks(1_ms);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800178 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700179
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800180 const Interest& interest = face.sentInterests[0];
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700181 BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
182 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
Eric Newberry2b765f82018-06-25 14:51:13 -0700183 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), true);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800184
Davide Pesavento0f830802018-01-16 23:58:58 -0500185 advanceClocks(98_ms);
Junxiao Shid5827ce2016-07-14 20:49:37 +0000186 BOOST_CHECK_EQUAL(nErrors, 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700187 BOOST_CHECK_EQUAL(nCompletions, 0);
Junxiao Shid5827ce2016-07-14 20:49:37 +0000188 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Eric Newberrye345baa2018-05-23 18:17:07 -0700189 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800190
Davide Pesavento0f830802018-01-16 23:58:58 -0500191 advanceClocks(1_ms, 2);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800192 BOOST_CHECK_EQUAL(nErrors, 1);
193 BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::INTEREST_TIMEOUT));
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800194 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
195 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Eric Newberrye345baa2018-05-23 18:17:07 -0700196 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 1);
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700197}
198
Eric Newberrye345baa2018-05-23 18:17:07 -0700199BOOST_AUTO_TEST_CASE(BasicSingleSegment)
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700200{
Alexander Afanasyev6dfeffe2017-01-30 22:40:32 -0800201 DummyValidator acceptValidator;
Eric Newberrycc910cd2018-05-06 17:01:40 -0700202 size_t nAfterSegmentReceived = 0;
203 size_t nAfterSegmentValidated = 0;
Eric Newberrye345baa2018-05-23 18:17:07 -0700204 size_t nAfterSegmentNacked = 0;
205 size_t nAfterSegmentTimedOut = 0;
206 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
Eric Newberrycc910cd2018-05-06 17:01:40 -0700207 acceptValidator);
208 connectSignals(fetcher);
209 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
210 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
Eric Newberrye345baa2018-05-23 18:17:07 -0700211 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
212 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500213
Davide Pesavento0f830802018-01-16 23:58:58 -0500214 advanceClocks(10_ms);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500215
Eric Newberrye345baa2018-05-23 18:17:07 -0700216 face.receive(*makeDataSegment("/hello/world/version0", 0, true));
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500217
Davide Pesavento0f830802018-01-16 23:58:58 -0500218 advanceClocks(10_ms);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500219
220 BOOST_CHECK_EQUAL(nErrors, 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700221 BOOST_CHECK_EQUAL(nCompletions, 1);
Eric Newberrye345baa2018-05-23 18:17:07 -0700222 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 1);
223 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 1);
224 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
225 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700226}
227
Eric Newberrye345baa2018-05-23 18:17:07 -0700228BOOST_AUTO_TEST_CASE(ConstantCwnd)
229{
230 SegmentFetcher::Options options;
231 options.useConstantCwnd = true;
232 DummyValidator acceptValidator;
233 size_t nAfterSegmentReceived = 0;
234 size_t nAfterSegmentValidated = 0;
235 size_t nAfterSegmentNacked = 0;
236 size_t nAfterSegmentTimedOut = 0;
237 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
238 acceptValidator, options);
239 connectSignals(fetcher);
240 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
241 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
242 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
243 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
244
245 advanceClocks(10_ms);
246
247 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
248 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
249
250 face.receive(*makeDataSegment("/hello/world/version0", 0, false));
251
252 advanceClocks(10_ms);
253
254 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
255 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
256 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2);
257 BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 1);
258 face.receive(*makeDataSegment("/hello/world/version0", 1, false));
259
260 advanceClocks(10_ms);
261
262 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
263 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
264 BOOST_CHECK_EQUAL(face.sentInterests.size(), 3);
265 BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 2);
266 face.receive(*makeDataSegment("/hello/world/version0", 2, false));
267
268 advanceClocks(10_ms);
269
270 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
271 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
272 BOOST_CHECK_EQUAL(face.sentInterests.size(), 4);
273 BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 3);
274 face.receive(*makeDataSegment("/hello/world/version0", 3, false));
275
276 advanceClocks(10_ms);
277
278 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
279 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
280 BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
281 BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 4);
282 nackLastInterest(lp::NackReason::CONGESTION);
283
284 advanceClocks(10_ms);
285
286 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
287 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
288 BOOST_CHECK_EQUAL(face.sentInterests.size(), 6);
289 BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 4);
290 face.receive(*makeDataSegment("/hello/world/version0", 4, true));
291
292 advanceClocks(10_ms);
293
294 BOOST_CHECK_EQUAL(nErrors, 0);
295 BOOST_CHECK_EQUAL(nCompletions, 1);
296 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 5);
297 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 5);
298 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 1);
299 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
300 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
301}
302
303BOOST_AUTO_TEST_CASE(BasicMultipleSegments)
Eric Newberrycc910cd2018-05-06 17:01:40 -0700304{
305 DummyValidator acceptValidator;
Eric Newberrye345baa2018-05-23 18:17:07 -0700306 size_t nAfterSegmentReceived = 0;
307 size_t nAfterSegmentValidated = 0;
308 size_t nAfterSegmentNacked = 0;
309 size_t nAfterSegmentTimedOut = 0;
310 nSegments = 401;
311 sendNackInsteadOfDropping = false;
312 face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
313
314 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
315 acceptValidator);
316 connectSignals(fetcher);
317 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
318 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
319 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
320 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
321
322 face.processEvents(1_s);
323
324 BOOST_CHECK_EQUAL(nErrors, 0);
325 BOOST_CHECK_EQUAL(nCompletions, 1);
326 BOOST_CHECK_EQUAL(dataSize, 14 * 401);
327 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
328 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
329 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
330 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
331}
332
333BOOST_AUTO_TEST_CASE(FirstSegmentNotZero)
334{
335 DummyValidator acceptValidator;
336 size_t nAfterSegmentReceived = 0;
337 size_t nAfterSegmentValidated = 0;
338 size_t nAfterSegmentNacked = 0;
339 size_t nAfterSegmentTimedOut = 0;
340 nSegments = 401;
341 sendNackInsteadOfDropping = false;
342 defaultSegmentToSend = 47;
343 face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
344
345 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
346 acceptValidator);
347 connectSignals(fetcher);
348 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
349 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
350 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
351 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
352
353 face.processEvents(1_s);
354
355 BOOST_CHECK_EQUAL(nErrors, 0);
356 BOOST_CHECK_EQUAL(nCompletions, 1);
357 BOOST_CHECK_EQUAL(dataSize, 14 * 401);
358 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
359 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
360 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
361 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
362}
363
364BOOST_AUTO_TEST_CASE(WindowSize)
365{
366 DummyValidator acceptValidator;
367 size_t nAfterSegmentReceived = 0;
368 size_t nAfterSegmentValidated = 0;
369 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
370 acceptValidator);
371 connectSignals(fetcher);
372 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
373 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
374
375 advanceClocks(10_ms); // T+10ms
376
377 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
378 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
379 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, 0);
380 BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
381 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, std::numeric_limits<double>::max());
382 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
383 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
384 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 0);
385 BOOST_CHECK_EQUAL(fetcher->m_highInterest, 0);
386 BOOST_CHECK_EQUAL(fetcher->m_highData, 0);
387 BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
388 BOOST_CHECK_EQUAL(fetcher->m_nReceived, 0);
389 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 0);
390 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), 1);
391 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
392
393 double oldCwnd = fetcher->m_cwnd;
394 double oldSsthresh = fetcher->m_ssthresh;
395 uint64_t oldNextSegmentNum = fetcher->m_nextSegmentNum;
396
397 face.receive(*makeDataSegment("/hello/world/version0", 0, false));
398
399 advanceClocks(10_ms); //T+20ms
400
401 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
402 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
403 BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
404 // +2 below because m_nextSegmentNum will be incremented in the receive callback if segment 0 is
405 // the first received
406 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 2);
407 BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
408 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
409 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd + fetcher->m_options.aiStep);
410 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
411 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 14);
412 BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
413 BOOST_CHECK_EQUAL(fetcher->m_highData, 0);
414 BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
415 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 1);
416 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
417 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1 + fetcher->m_cwnd);
418
419 oldCwnd = fetcher->m_cwnd;
420 oldNextSegmentNum = fetcher->m_nextSegmentNum;
421
422 face.receive(*makeDataSegment("/hello/world/version0", 2, false));
423
424 advanceClocks(10_ms); //T+30ms
425
426 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
427 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
428 BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
429 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 1);
430 BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
431 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
432 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, fetcher->m_cwnd);
433 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
434 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 28);
435 BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
436 BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
437 BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
438 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 2);
439 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
440 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2 + fetcher->m_cwnd);
441
442 oldCwnd = fetcher->m_cwnd;
443 oldNextSegmentNum = fetcher->m_nextSegmentNum;
444
445 face.receive(*makeDataSegment("/hello/world/version0", 1, false));
446
447 advanceClocks(10_ms); //T+40ms
448
449 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
450 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
451 BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
452 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 1);
453 BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
454 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
455 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, fetcher->m_cwnd);
456 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
457 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
458 BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
459 BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
460 BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
461 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
462 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
463 BOOST_CHECK_EQUAL(face.sentInterests.size(), 3 + fetcher->m_cwnd);
464
465 oldCwnd = fetcher->m_cwnd;
466 oldSsthresh = fetcher->m_ssthresh;
467 oldNextSegmentNum = fetcher->m_nextSegmentNum;
468 size_t oldSentInterestsSize = face.sentInterests.size();
469
470 nackLastInterest(lp::NackReason::CONGESTION); //T+50ms
471
472 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 20_ms);
473 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 1);
474 BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
475 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum);
476 BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd / 2.0);
477 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldCwnd / 2.0);
478 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd - 1);
479 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
480 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
481 BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
482 BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
483 BOOST_CHECK_EQUAL(fetcher->m_recPoint, fetcher->m_nextSegmentNum - 1);
484 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
485 // The Nacked segment will remain in pendingSegments, so the size of the structure doesn't change
486 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), oldCwnd);
487 BOOST_CHECK_EQUAL(face.sentInterests.size(), oldSentInterestsSize);
488
489 advanceClocks(10_ms); //T+60ms
490
491 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 30_ms);
492 BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 1);
493 BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
494 BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum);
495 BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd / 2.0);
496 BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldCwnd / 2.0);
497 BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd - 1);
498 BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
499 BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
500 BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
501 BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
502 BOOST_CHECK_EQUAL(fetcher->m_recPoint, fetcher->m_nextSegmentNum - 1);
503 BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
504 BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), oldCwnd);
505 BOOST_CHECK_EQUAL(face.sentInterests.size(), oldSentInterestsSize);
506
507 // Properly end test case
508 lp::Nack nack = makeNack(face.sentInterests[face.sentInterests.size() - 2], lp::NackReason::NO_ROUTE);
509 face.receive(nack);
510 advanceClocks(10_ms); //T+70ms
511
512 BOOST_CHECK_EQUAL(nErrors, 1);
513 BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::NACK_ERROR));
514 BOOST_CHECK_EQUAL(nCompletions, 0);
515}
516
517BOOST_AUTO_TEST_CASE(MissingSegmentNum)
518{
519 DummyValidator acceptValidator;
520 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
Eric Newberrycc910cd2018-05-06 17:01:40 -0700521 acceptValidator);
522 connectSignals(fetcher);
523
524 advanceClocks(10_ms);
525
526 const uint8_t buffer[] = "Hello, world!";
527 auto data = makeData("/hello/world/version0/no-segment");
528 data->setContent(buffer, sizeof(buffer));
529
530 face.receive(*data);
531 advanceClocks(10_ms);
532
533 BOOST_CHECK_EQUAL(nErrors, 1);
534 BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::DATA_HAS_NO_SEGMENT));
535 BOOST_CHECK_EQUAL(nCompletions, 0);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500536}
537
Eric Newberrye345baa2018-05-23 18:17:07 -0700538BOOST_AUTO_TEST_CASE(MoreSegmentsThanNSegments)
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500539{
Eric Newberrycc910cd2018-05-06 17:01:40 -0700540 DummyValidator acceptValidator;
Eric Newberrye345baa2018-05-23 18:17:07 -0700541 size_t nAfterSegmentReceived = 0;
542 size_t nAfterSegmentValidated = 0;
543 size_t nAfterSegmentNacked = 0;
544 size_t nAfterSegmentTimedOut = 0;
545 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
Eric Newberrycc910cd2018-05-06 17:01:40 -0700546 acceptValidator);
547 connectSignals(fetcher);
Eric Newberrye345baa2018-05-23 18:17:07 -0700548 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
549 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
550 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
551 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
552
Davide Pesavento0f830802018-01-16 23:58:58 -0500553 advanceClocks(10_ms);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500554
Eric Newberrye345baa2018-05-23 18:17:07 -0700555 face.receive(*makeDataSegment("/hello/world/version0", 0, false));
Davide Pesavento0f830802018-01-16 23:58:58 -0500556 advanceClocks(10_ms);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500557
Eric Newberrye345baa2018-05-23 18:17:07 -0700558 BOOST_CHECK_EQUAL(nErrors, 0);
559 BOOST_CHECK_EQUAL(nCompletions, 0);
Muktadir R Chowdhuryf58f8f42015-09-02 11:56:49 -0500560
Eric Newberrye345baa2018-05-23 18:17:07 -0700561 face.receive(*makeDataSegment("/hello/world/version0", 1, false));
Davide Pesavento0f830802018-01-16 23:58:58 -0500562 advanceClocks(10_ms);
Muktadir R Chowdhury2bc2df02016-04-05 16:55:41 -0500563
Eric Newberrye345baa2018-05-23 18:17:07 -0700564 BOOST_CHECK_EQUAL(nErrors, 0);
565 BOOST_CHECK_EQUAL(nCompletions, 0);
566
567 face.receive(*makeDataSegment("/hello/world/version0", 2, false));
568 advanceClocks(10_ms);
569
570 BOOST_CHECK_EQUAL(nErrors, 0);
571 BOOST_CHECK_EQUAL(nCompletions, 0);
572
573 face.receive(*makeDataSegment("/hello/world/version0", 3, false));
574 advanceClocks(10_ms);
575
576 BOOST_CHECK_EQUAL(nErrors, 0);
577 BOOST_CHECK_EQUAL(nCompletions, 0);
578
579 auto data4 = makeDataSegment("/hello/world/version0", 4, false);
580 data4->setFinalBlock(name::Component::fromSegment(2));
581 face.receive(*data4);
582 advanceClocks(10_ms);
583
584 BOOST_CHECK_EQUAL(nErrors, 0);
585 BOOST_CHECK_EQUAL(nCompletions, 1);
586 BOOST_CHECK_EQUAL(dataSize, 14 * 3);
587 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 5);
588 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 5);
589 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
590 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
Muktadir R Chowdhury2bc2df02016-04-05 16:55:41 -0500591}
592
Eric Newberrye345baa2018-05-23 18:17:07 -0700593BOOST_AUTO_TEST_CASE(DuplicateNack)
594{
595 DummyValidator acceptValidator;
596 size_t nAfterSegmentReceived = 0;
597 size_t nAfterSegmentValidated = 0;
598 size_t nAfterSegmentNacked = 0;
599 size_t nAfterSegmentTimedOut = 0;
600 nSegments = 401;
601 segmentsToDropOrNack.push(0);
602 segmentsToDropOrNack.push(200);
603 sendNackInsteadOfDropping = true;
604 nackReason = lp::NackReason::DUPLICATE;
605 face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
606
607 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
608 acceptValidator);
609 connectSignals(fetcher);
610 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
611 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
612 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
613 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
614
615 face.processEvents(1_s);
616
617 BOOST_CHECK_EQUAL(nErrors, 0);
618 BOOST_CHECK_EQUAL(nCompletions, 1);
619 BOOST_CHECK_EQUAL(dataSize, 14 * 401);
620 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
621 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
622 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 2);
623 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
624}
625
626BOOST_AUTO_TEST_CASE(CongestionNack)
627{
628 DummyValidator acceptValidator;
629 size_t nAfterSegmentReceived = 0;
630 size_t nAfterSegmentValidated = 0;
631 size_t nAfterSegmentNacked = 0;
632 size_t nAfterSegmentTimedOut = 0;
633 nSegments = 401;
634 segmentsToDropOrNack.push(0);
635 segmentsToDropOrNack.push(200);
636 sendNackInsteadOfDropping = true;
637 nackReason = lp::NackReason::CONGESTION;
638 face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
639
640 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
641 acceptValidator);
642 connectSignals(fetcher);
643 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
644 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
645 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
646 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
647
648 face.processEvents(1_s);
649
650 BOOST_CHECK_EQUAL(nErrors, 0);
651 BOOST_CHECK_EQUAL(nCompletions, 1);
652 BOOST_CHECK_EQUAL(dataSize, 14 * 401);
653 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
654 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
655 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 2);
656 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
657}
658
659BOOST_AUTO_TEST_CASE(OtherNackReason)
660{
661 DummyValidator acceptValidator;
662 size_t nAfterSegmentReceived = 0;
663 size_t nAfterSegmentValidated = 0;
664 size_t nAfterSegmentNacked = 0;
665 size_t nAfterSegmentTimedOut = 0;
666 segmentsToDropOrNack.push(0);
667 sendNackInsteadOfDropping = true;
668 nackReason = lp::NackReason::NO_ROUTE;
669 face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
670
671 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
672 acceptValidator);
673 connectSignals(fetcher);
674 fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
675 fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
676 fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
677 fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
678
679 face.processEvents(1_s);
680
681 BOOST_CHECK_EQUAL(nErrors, 1);
682 BOOST_CHECK_EQUAL(nCompletions, 0);
683 BOOST_CHECK_EQUAL(nAfterSegmentReceived, 0);
684 BOOST_CHECK_EQUAL(nAfterSegmentValidated, 0);
685 BOOST_CHECK_EQUAL(nAfterSegmentNacked, 1);
686 BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
687 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
688}
689
690BOOST_AUTO_TEST_CASE(ValidationFailure)
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000691{
692 DummyValidator validator;
Eric Newberrycc910cd2018-05-06 17:01:40 -0700693 validator.getPolicy().setResultCallback([] (const Name& name) {
694 return name.at(-1).toSegment() % 2 == 0;
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000695 });
Eric Newberrye345baa2018-05-23 18:17:07 -0700696 shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
Eric Newberrycc910cd2018-05-06 17:01:40 -0700697 validator);
698 connectSignals(fetcher);
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000699
700 auto data1 = makeDataSegment("/hello/world", 0, false);
701 auto data2 = makeDataSegment("/hello/world", 1, true);
702
703 size_t nRecvSegments = 0;
704 fetcher->afterSegmentReceived.connect([&nRecvSegments] (const Data& receivedSegment) {
705 ++nRecvSegments;
706 });
707
708 size_t nValidatedSegments = 0;
709 fetcher->afterSegmentValidated.connect([&nValidatedSegments] (const Data& validatedSegment) {
710 ++nValidatedSegments;
711 });
712
Davide Pesavento0f830802018-01-16 23:58:58 -0500713 advanceClocks(10_ms, 10);
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000714
Eric Newberrye345baa2018-05-23 18:17:07 -0700715 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 100_ms);
716
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000717 face.receive(*data1);
718
Davide Pesavento0f830802018-01-16 23:58:58 -0500719 advanceClocks(10_ms, 10);
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000720
Eric Newberrye345baa2018-05-23 18:17:07 -0700721 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 100_ms);
722
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000723 face.receive(*data2);
724
Davide Pesavento0f830802018-01-16 23:58:58 -0500725 advanceClocks(10_ms, 10);
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000726
Eric Newberrye345baa2018-05-23 18:17:07 -0700727 BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 200_ms);
Muktadir Chowdhury1c109b42018-01-10 08:36:00 +0000728 BOOST_CHECK_EQUAL(nRecvSegments, 2);
729 BOOST_CHECK_EQUAL(nValidatedSegments, 1);
730 BOOST_CHECK_EQUAL(nErrors, 1);
731}
732
Eric Newberrycc910cd2018-05-06 17:01:40 -0700733// Tests deprecated `fetch` API that uses callbacks instead of signals. This test case will be
734// removed when this API is removed.
Eric Newberrye345baa2018-05-23 18:17:07 -0700735BOOST_AUTO_TEST_CASE(DeprecatedFetch)
Eric Newberrycc910cd2018-05-06 17:01:40 -0700736{
737 DummyValidator acceptValidator;
738 SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
739 acceptValidator,
740 bind(&Fixture::onComplete, this, _1),
741 bind(&Fixture::onError, this, _1));
742
743 advanceClocks(10_ms);
744
745 face.receive(*makeDataSegment("/hello/world/version0", 0, true));
746 advanceClocks(10_ms);
747
748 BOOST_CHECK_EQUAL(nErrors, 0);
749 BOOST_CHECK_EQUAL(nCompletions, 1);
750
751 BOOST_CHECK_EQUAL(dataSize, 14);
752
Eric Newberrye345baa2018-05-23 18:17:07 -0700753 const uint8_t buffer[] = "Hello, world!\0";
754 BOOST_REQUIRE_EQUAL(dataBuf->size(), 14);
755 BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + 14);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700756
Eric Newberrye345baa2018-05-23 18:17:07 -0700757 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700758 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
759 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
760
761 const Interest& interest = face.sentInterests[0];
762 BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
763 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
Eric Newberry2b765f82018-06-25 14:51:13 -0700764 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), true);
Eric Newberrye345baa2018-05-23 18:17:07 -0700765 BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
766}
767
768// Tests deprecated `fetch` API that uses callbacks instead of signals. This test case will be
769// removed when this API is removed.
770BOOST_AUTO_TEST_CASE(DeprecatedFetchMultipleSegments)
771{
772 DummyValidator acceptValidator;
773 SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
774 acceptValidator,
775 bind(&Fixture::onComplete, this, _1),
776 bind(&Fixture::onError, this, _1));
777
778 advanceClocks(10_ms);
779
780 face.receive(*makeDataSegment("/hello/world/version0", 0, false));
781 advanceClocks(10_ms);
782
783 face.receive(*makeDataSegment("/hello/world/version0", 1, false));
784 advanceClocks(10_ms);
785
786 face.receive(*makeDataSegment("/hello/world/version0", 2, true));
787 advanceClocks(10_ms);
788
789 BOOST_CHECK_EQUAL(nErrors, 0);
790 BOOST_CHECK_EQUAL(nCompletions, 1);
791
792 BOOST_CHECK_EQUAL(dataSize, 14 * 3);
793
794 const uint8_t buffer[] = "Hello, world!\0Hello, world!\0Hello, world!\0";
795 BOOST_REQUIRE_EQUAL(dataBuf->size(), 14 * 3);
796 BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + (14 * 3));
797
798 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
799 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 3);
800 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
801
802 const Interest& interest0 = face.sentInterests[0];
803 BOOST_CHECK_EQUAL(interest0.getName(), "/hello/world");
804 BOOST_CHECK_EQUAL(interest0.getMustBeFresh(), true);
Eric Newberry2b765f82018-06-25 14:51:13 -0700805 BOOST_CHECK_EQUAL(interest0.getCanBePrefix(), true);
Eric Newberrye345baa2018-05-23 18:17:07 -0700806 BOOST_CHECK_EQUAL(interest0.getInterestLifetime(), 1000_s);
807
808 const Interest& interest1 = face.sentInterests[1];
809 BOOST_CHECK_EQUAL(interest1.getName(), "/hello/world/version0/%00%01");
810 BOOST_CHECK_EQUAL(interest1.getMustBeFresh(), false);
Eric Newberry2b765f82018-06-25 14:51:13 -0700811 BOOST_CHECK_EQUAL(interest1.getCanBePrefix(), false);
Eric Newberrye345baa2018-05-23 18:17:07 -0700812 BOOST_CHECK_EQUAL(interest1.getInterestLifetime(), 1000_s);
813
814 const Interest& interest2 = face.sentInterests[2];
815 BOOST_CHECK_EQUAL(interest2.getName(), "/hello/world/version0/%00%02");
816 BOOST_CHECK_EQUAL(interest2.getMustBeFresh(), false);
Eric Newberry2b765f82018-06-25 14:51:13 -0700817 BOOST_CHECK_EQUAL(interest2.getCanBePrefix(), false);
Eric Newberrye345baa2018-05-23 18:17:07 -0700818 BOOST_CHECK_EQUAL(interest2.getInterestLifetime(), 1000_s);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700819}
820
821// Tests deprecated `fetch` API that uses callbacks instead of signals (with an accepting shared_ptr
822// Validator). This test case will be removed when this API is removed.
Eric Newberrye345baa2018-05-23 18:17:07 -0700823BOOST_AUTO_TEST_CASE(DeprecatedFetchSharedPtrComplete)
Eric Newberrycc910cd2018-05-06 17:01:40 -0700824{
825 auto acceptValidator = make_shared<DummyValidator>(true);
826 SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
827 acceptValidator,
828 bind(&Fixture::onComplete, this, _1),
829 bind(&Fixture::onError, this, _1));
830
831 weak_ptr<DummyValidator> weakValidator = acceptValidator;
832 BOOST_CHECK(!weakValidator.expired());
833 acceptValidator.reset();
834 BOOST_CHECK(!weakValidator.expired());
835
836 advanceClocks(10_ms);
837
838 BOOST_CHECK(!weakValidator.expired());
839 face.receive(*makeDataSegment("/hello/world/version0", 0, true));
840
841 advanceClocks(10_ms);
842
843 BOOST_CHECK(weakValidator.expired());
844 BOOST_CHECK_EQUAL(nErrors, 0);
845 BOOST_CHECK_EQUAL(nCompletions, 1);
846
847 BOOST_CHECK_EQUAL(dataSize, 14);
848
Eric Newberrye345baa2018-05-23 18:17:07 -0700849 const uint8_t buffer[] = "Hello, world!\0";
850 BOOST_REQUIRE_EQUAL(dataBuf->size(), 14);
851 BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + 14);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700852
Eric Newberrye345baa2018-05-23 18:17:07 -0700853 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700854 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
855 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
856
857 const Interest& interest = face.sentInterests[0];
858 BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
859 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
Eric Newberry2b765f82018-06-25 14:51:13 -0700860 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), true);
Eric Newberrye345baa2018-05-23 18:17:07 -0700861 BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700862}
863
864// Tests deprecated `fetch` API that uses callbacks instead of signals (with a rejecting shared_ptr
865// Validator). This test case will be removed when this API is removed.
Eric Newberrye345baa2018-05-23 18:17:07 -0700866BOOST_AUTO_TEST_CASE(DeprecatedFetchSharedPtrError)
Eric Newberrycc910cd2018-05-06 17:01:40 -0700867{
868 auto acceptValidator = make_shared<DummyValidator>(false);
869 SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
870 acceptValidator,
871 bind(&Fixture::onComplete, this, _1),
872 bind(&Fixture::onError, this, _1));
873
874 weak_ptr<DummyValidator> weakValidator = acceptValidator;
875 BOOST_CHECK(!weakValidator.expired());
876 acceptValidator.reset();
877 BOOST_CHECK(!weakValidator.expired());
878
879 advanceClocks(10_ms);
880
881 BOOST_CHECK(!weakValidator.expired());
882 face.receive(*makeDataSegment("/hello/world/version0", 0, true));
883
884 advanceClocks(10_ms);
885
886 BOOST_CHECK(weakValidator.expired());
887 BOOST_CHECK_EQUAL(nErrors, 1);
888 BOOST_CHECK_EQUAL(nCompletions, 0);
889
Eric Newberrye345baa2018-05-23 18:17:07 -0700890 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700891 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
892 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
893
894 const Interest& interest = face.sentInterests[0];
895 BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
896 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
Eric Newberry2b765f82018-06-25 14:51:13 -0700897 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), true);
Eric Newberrye345baa2018-05-23 18:17:07 -0700898 BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
Eric Newberrycc910cd2018-05-06 17:01:40 -0700899}
900
Junxiao Shid5827ce2016-07-14 20:49:37 +0000901BOOST_AUTO_TEST_SUITE_END() // TestSegmentFetcher
902BOOST_AUTO_TEST_SUITE_END() // Util
Alexander Afanasyevf3cfab52014-08-17 22:15:25 -0700903
904} // namespace tests
905} // namespace util
906} // namespace ndn