blob: bd705c74d9336b84a5047c94f7a50b69ef756b1f [file] [log] [blame]
Teng Liang7003e0b2018-03-03 16:03:30 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
ashiqopud3ae85d2019-02-17 02:29:55 +00003 * Copyright (c) 2014-2019, Regents of the University of California,
Teng Liang7003e0b2018-03-03 16:03:30 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
Teng Liang7003e0b2018-03-03 16:03:30 -070026#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040027#include "tests/daemon/global-io-fixture.hpp"
28#include "tests/daemon/face/dummy-face.hpp"
29#include "choose-strategy.hpp"
30#include "dummy-strategy.hpp"
Teng Liang7003e0b2018-03-03 16:03:30 -070031
Teng Liang85a36632018-03-21 05:59:34 -070032#include <ndn-cxx/lp/tags.hpp>
33
Teng Liang7003e0b2018-03-03 16:03:30 -070034namespace nfd {
35namespace fw {
36namespace tests {
37
38using namespace nfd::tests;
39
40BOOST_AUTO_TEST_SUITE(Fw)
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040041BOOST_FIXTURE_TEST_SUITE(TestPitExpiry, GlobalIoTimeFixture)
Teng Liang7003e0b2018-03-03 16:03:30 -070042
43class PitExpiryTestStrategy : public DummyStrategy
44{
45public:
46 static Name
47 getStrategyName(uint64_t version)
48 {
49 return Name("/PitExpiryTestStrategy").appendVersion(version);
50 }
51
52 static void
53 registerAs(const Name& strategyName)
54 {
55 registerAsImpl<PitExpiryTestStrategy>(strategyName);
56 }
57
58 explicit
59 PitExpiryTestStrategy(Forwarder& forwarder, const Name& name = getStrategyName(1))
60 : DummyStrategy(forwarder, name)
61 {
62 }
63
64 void
ashiqopuc7079482019-02-20 05:34:37 +000065 afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
Teng Liang7003e0b2018-03-03 16:03:30 -070066 const shared_ptr<pit::Entry>& pitEntry) override
67 {
ashiqopuc7079482019-02-20 05:34:37 +000068 DummyStrategy::afterReceiveInterest(ingress, interest, pitEntry);
Teng Liang7003e0b2018-03-03 16:03:30 -070069
70 if (afterReceiveInterest_count <= 1) {
71 setExpiryTimer(pitEntry, 190_ms);
72 }
73 }
74
75 void
76 beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
ashiqopuc7079482019-02-20 05:34:37 +000077 const FaceEndpoint& ingress, const Data& data) override
Teng Liang7003e0b2018-03-03 16:03:30 -070078 {
ashiqopuc7079482019-02-20 05:34:37 +000079 DummyStrategy::beforeSatisfyInterest(pitEntry, ingress, data);
Teng Liang7003e0b2018-03-03 16:03:30 -070080
Teng Liang43bb2312018-03-26 04:16:42 -070081 if (beforeSatisfyInterest_count <= 2) {
Teng Liang7003e0b2018-03-03 16:03:30 -070082 setExpiryTimer(pitEntry, 190_ms);
83 }
84 }
85
86 void
Teng Liang85a36632018-03-21 05:59:34 -070087 afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
ashiqopuc7079482019-02-20 05:34:37 +000088 const FaceEndpoint& ingress, const Data& data) override
Teng Liang85a36632018-03-21 05:59:34 -070089 {
90 if (afterContentStoreHit_count == 0) {
91 setExpiryTimer(pitEntry, 190_ms);
92 }
93
ashiqopuc7079482019-02-20 05:34:37 +000094 DummyStrategy::afterContentStoreHit(pitEntry, ingress, data);
Teng Liang85a36632018-03-21 05:59:34 -070095 }
96
97 void
Teng Liang43bb2312018-03-26 04:16:42 -070098 afterReceiveData(const shared_ptr<pit::Entry>& pitEntry,
ashiqopuc7079482019-02-20 05:34:37 +000099 const FaceEndpoint& ingress, const Data& data) override
Teng Liang43bb2312018-03-26 04:16:42 -0700100 {
101 ++afterReceiveData_count;
102
103 if (afterReceiveData_count <= 2) {
104 setExpiryTimer(pitEntry, 290_ms);
105 }
106
ashiqopuc7079482019-02-20 05:34:37 +0000107 this->sendDataToAll(pitEntry, ingress, data);
Teng Liang43bb2312018-03-26 04:16:42 -0700108 }
109
110 void
ashiqopuc7079482019-02-20 05:34:37 +0000111 afterReceiveNack(const FaceEndpoint& ingress, const lp::Nack& nack,
Teng Liang7003e0b2018-03-03 16:03:30 -0700112 const shared_ptr<pit::Entry>& pitEntry) override
113 {
ashiqopuc7079482019-02-20 05:34:37 +0000114 DummyStrategy::afterReceiveNack(ingress, nack, pitEntry);
Teng Liang7003e0b2018-03-03 16:03:30 -0700115
116 if (afterReceiveNack_count <= 1) {
117 setExpiryTimer(pitEntry, 50_ms);
118 }
119 }
120};
121
122BOOST_AUTO_TEST_CASE(UnsatisfiedInterest)
123{
124 Forwarder forwarder;
125
126 auto face1 = make_shared<DummyFace>();
127 auto face2 = make_shared<DummyFace>();
128 forwarder.addFace(face1);
129 forwarder.addFace(face2);
130
131 Pit& pit = forwarder.getPit();
132
Junxiao Shi9d727852019-05-14 13:44:22 -0600133 auto interest1 = makeInterest("/A/0");
134 auto interest2 = makeInterest("/A/1");
Teng Liang7003e0b2018-03-03 16:03:30 -0700135 interest1->setInterestLifetime(90_ms);
136 interest2->setInterestLifetime(90_ms);
137
ashiqopu075bb7d2019-03-10 01:38:21 +0000138 face1->receiveInterest(*interest1, 0);
139 face2->receiveInterest(*interest2, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700140 BOOST_CHECK_EQUAL(pit.size(), 2);
141
142 this->advanceClocks(100_ms);
143 BOOST_CHECK_EQUAL(pit.size(), 0);
144}
145
146BOOST_AUTO_TEST_CASE(SatisfiedInterest)
147{
148 Forwarder forwarder;
149
150 auto face1 = make_shared<DummyFace>();
151 auto face2 = make_shared<DummyFace>();
152 forwarder.addFace(face1);
153 forwarder.addFace(face2);
154
155 Pit& pit = forwarder.getPit();
156
Junxiao Shi9d727852019-05-14 13:44:22 -0600157 auto interest = makeInterest("/A/0");
Teng Liang7003e0b2018-03-03 16:03:30 -0700158 interest->setInterestLifetime(90_ms);
Junxiao Shi9d727852019-05-14 13:44:22 -0600159 auto data = makeData("/A/0");
Teng Liang7003e0b2018-03-03 16:03:30 -0700160
ashiqopu075bb7d2019-03-10 01:38:21 +0000161 face1->receiveInterest(*interest, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700162
163 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000164 face2->receiveData(*data, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700165
166 this->advanceClocks(1_ms);
167 BOOST_CHECK_EQUAL(pit.size(), 0);
168}
169
Teng Liang85a36632018-03-21 05:59:34 -0700170BOOST_AUTO_TEST_CASE(CsHit)
171{
172 Forwarder forwarder;
173
174 auto face1 = make_shared<DummyFace>();
175 auto face2 = make_shared<DummyFace>();
176 forwarder.addFace(face1);
177 forwarder.addFace(face2);
178
179 Name strategyA("/strategyA/%FD%01");
180 PitExpiryTestStrategy::registerAs(strategyA);
181 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
182
Junxiao Shi9d727852019-05-14 13:44:22 -0600183 auto interest = makeInterest("/A/0");
Teng Liang85a36632018-03-21 05:59:34 -0700184 interest->setInterestLifetime(90_ms);
185
Junxiao Shi9d727852019-05-14 13:44:22 -0600186 auto data = makeData("/A/0");
Teng Liang85a36632018-03-21 05:59:34 -0700187 data->setTag(make_shared<lp::IncomingFaceIdTag>(face2->getId()));
188
189 Pit& pit = forwarder.getPit();
190 BOOST_CHECK_EQUAL(pit.size(), 0);
191
192 Cs& cs = forwarder.getCs();
193 cs.insert(*data);
194
ashiqopu075bb7d2019-03-10 01:38:21 +0000195 face1->receiveInterest(*interest, 0);
Teng Liang85a36632018-03-21 05:59:34 -0700196 this->advanceClocks(1_ms);
197 BOOST_CHECK_EQUAL(pit.size(), 1);
198
199 this->advanceClocks(190_ms);
200 BOOST_CHECK_EQUAL(pit.size(), 0);
201
ashiqopu075bb7d2019-03-10 01:38:21 +0000202 face1->receiveInterest(*interest, 0);
Teng Liang85a36632018-03-21 05:59:34 -0700203 this->advanceClocks(1_ms);
204 BOOST_CHECK_EQUAL(pit.size(), 0);
205}
206
Teng Liang7003e0b2018-03-03 16:03:30 -0700207BOOST_AUTO_TEST_CASE(ReceiveNack)
208{
209 Forwarder forwarder;
210
211 auto face1 = make_shared<DummyFace>();
212 auto face2 = make_shared<DummyFace>();
213 auto face3 = make_shared<DummyFace>();
214 forwarder.addFace(face1);
215 forwarder.addFace(face2);
216 forwarder.addFace(face3);
217
218 Name strategyA("/strategyA/%FD%01");
219 PitExpiryTestStrategy::registerAs(strategyA);
220 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
221
222 Pit& pit = forwarder.getPit();
223
Junxiao Shi9d727852019-05-14 13:44:22 -0600224 auto interest = makeInterest("/A/0", false, 90_ms, 562);
225 lp::Nack nack = makeNack(*interest, lp::NackReason::CONGESTION);
Teng Liang7003e0b2018-03-03 16:03:30 -0700226
ashiqopu075bb7d2019-03-10 01:38:21 +0000227 face1->receiveInterest(*interest, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700228 auto entry = pit.find(*interest);
ashiqopud3ae85d2019-02-17 02:29:55 +0000229 entry->insertOrUpdateOutRecord(*face2, 0, *interest);
230 entry->insertOrUpdateOutRecord(*face3, 0, *interest);
Teng Liang7003e0b2018-03-03 16:03:30 -0700231
232 this->advanceClocks(10_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000233 face2->receiveNack(nack, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700234
235 this->advanceClocks(1_ms);
236 BOOST_CHECK_EQUAL(pit.size(), 1);
237
238 this->advanceClocks(50_ms);
239 BOOST_CHECK_EQUAL(pit.size(), 0);
240}
241
242BOOST_AUTO_TEST_CASE(ResetTimerAfterReceiveInterest)
243{
244 Forwarder forwarder;
245
246 auto face = make_shared<DummyFace>();
247 forwarder.addFace(face);
248
249 Name strategyA("/strategyA/%FD%01");
250 PitExpiryTestStrategy::registerAs(strategyA);
251 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
252
253 Pit& pit = forwarder.getPit();
254
Junxiao Shi9d727852019-05-14 13:44:22 -0600255 auto interest = makeInterest("/A/0", false, 90_ms);
Teng Liang7003e0b2018-03-03 16:03:30 -0700256
ashiqopu075bb7d2019-03-10 01:38:21 +0000257 face->receiveInterest(*interest, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700258 BOOST_CHECK_EQUAL(pit.size(), 1);
259
260 this->advanceClocks(100_ms);
261 BOOST_CHECK_EQUAL(pit.size(), 1);
262
263 this->advanceClocks(100_ms);
264 BOOST_CHECK_EQUAL(pit.size(), 0);
265}
266
267BOOST_AUTO_TEST_CASE(ResetTimerBeforeSatisfyInterest)
268{
269 Forwarder forwarder;
270
271 auto face1 = make_shared<DummyFace>();
272 auto face2 = make_shared<DummyFace>();
Teng Liang43bb2312018-03-26 04:16:42 -0700273 auto face3 = make_shared<DummyFace>();
274 forwarder.addFace(face1);
275 forwarder.addFace(face2);
276 forwarder.addFace(face3);
277
278 Name strategyA("/strategyA/%FD%01");
279 Name strategyB("/strategyB/%FD%01");
280 PitExpiryTestStrategy::registerAs(strategyA);
281 PitExpiryTestStrategy::registerAs(strategyB);
282 auto& sA = choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
283 auto& sB = choose<PitExpiryTestStrategy>(forwarder, "/A/0", strategyB);
284 Pit& pit = forwarder.getPit();
285
Junxiao Shi9d727852019-05-14 13:44:22 -0600286 auto interest1 = makeInterest("/A", true, 90_ms);
287 auto interest2 = makeInterest("/A/0", false, 90_ms);
288 auto data = makeData("/A/0");
Teng Liang43bb2312018-03-26 04:16:42 -0700289
ashiqopu075bb7d2019-03-10 01:38:21 +0000290 face1->receiveInterest(*interest1, 0);
291 face2->receiveInterest(*interest2, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700292 BOOST_CHECK_EQUAL(pit.size(), 2);
293
294 // beforeSatisfyInterest: the first Data prolongs PIT expiry timer by 190 ms
295 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000296 face3->receiveData(*data, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700297 this->advanceClocks(189_ms);
298 BOOST_CHECK_EQUAL(pit.size(), 2);
299 this->advanceClocks(2_ms);
300 BOOST_CHECK_EQUAL(pit.size(), 0);
301
ashiqopu075bb7d2019-03-10 01:38:21 +0000302 face1->receiveInterest(*interest1, 0);
303 face2->receiveInterest(*interest2, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700304
305 // beforeSatisfyInterest: the second Data prolongs PIT expiry timer
306 // and the third one sets the timer to now
307 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000308 face3->receiveData(*data, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700309 this->advanceClocks(1_ms);
310 BOOST_CHECK_EQUAL(pit.size(), 2);
311
312 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000313 face3->receiveData(*data, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700314 this->advanceClocks(1_ms);
315 BOOST_CHECK_EQUAL(pit.size(), 0);
316
317 BOOST_CHECK_EQUAL(sA.beforeSatisfyInterest_count, 3);
318 BOOST_CHECK_EQUAL(sB.beforeSatisfyInterest_count, 3);
319 BOOST_CHECK_EQUAL(sA.afterReceiveData_count, 0);
320 BOOST_CHECK_EQUAL(sB.afterReceiveData_count, 0);
321}
322
323BOOST_AUTO_TEST_CASE(ResetTimerAfterReceiveData)
324{
325 Forwarder forwarder;
326
327 auto face1 = make_shared<DummyFace>();
328 auto face2 = make_shared<DummyFace>();
Teng Liang7003e0b2018-03-03 16:03:30 -0700329 forwarder.addFace(face1);
330 forwarder.addFace(face2);
331
332 Name strategyA("/strategyA/%FD%01");
333 PitExpiryTestStrategy::registerAs(strategyA);
Teng Liang43bb2312018-03-26 04:16:42 -0700334 auto& sA = choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
Teng Liang7003e0b2018-03-03 16:03:30 -0700335
336 Pit& pit = forwarder.getPit();
337
Junxiao Shi9d727852019-05-14 13:44:22 -0600338 auto interest = makeInterest("/A/0", false, 90_ms);
339 auto data = makeData("/A/0");
Teng Liang7003e0b2018-03-03 16:03:30 -0700340
ashiqopu075bb7d2019-03-10 01:38:21 +0000341 face1->receiveInterest(*interest, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700342
Teng Liang43bb2312018-03-26 04:16:42 -0700343 // afterReceiveData: the first Data prolongs PIT expiry timer by 290 ms
Teng Liang7003e0b2018-03-03 16:03:30 -0700344 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000345 face2->receiveData(*data, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700346 this->advanceClocks(289_ms);
347 BOOST_CHECK_EQUAL(pit.size(), 1);
348 this->advanceClocks(2_ms);
349 BOOST_CHECK_EQUAL(pit.size(), 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700350
ashiqopu075bb7d2019-03-10 01:38:21 +0000351 face1->receiveInterest(*interest, 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700352
353 // afterReceiveData: the second Data prolongs PIT expiry timer
354 // and the third one sets the timer to now
355 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000356 face2->receiveData(*data, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700357 this->advanceClocks(1_ms);
358 BOOST_CHECK_EQUAL(pit.size(), 1);
359
360 this->advanceClocks(30_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000361 face2->receiveData(*data, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700362 this->advanceClocks(1_ms);
363 BOOST_CHECK_EQUAL(pit.size(), 0);
Teng Liang43bb2312018-03-26 04:16:42 -0700364
365 BOOST_CHECK_EQUAL(sA.beforeSatisfyInterest_count, 0);
366 BOOST_CHECK_EQUAL(sA.afterReceiveData_count, 3);
Teng Liang7003e0b2018-03-03 16:03:30 -0700367}
368
369BOOST_AUTO_TEST_CASE(ReceiveNackAfterResetTimer)
370{
371 Forwarder forwarder;
372
373 auto face1 = make_shared<DummyFace>();
374 auto face2 = make_shared<DummyFace>();
375 auto face3 = make_shared<DummyFace>();
376 forwarder.addFace(face1);
377 forwarder.addFace(face2);
378 forwarder.addFace(face3);
379
380 Name strategyA("/strategyA/%FD%01");
381 PitExpiryTestStrategy::registerAs(strategyA);
382 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
383
384 Pit& pit = forwarder.getPit();
385
Junxiao Shi9d727852019-05-14 13:44:22 -0600386 auto interest = makeInterest("/A/0", false, 90_ms, 562);
387 lp::Nack nack = makeNack(*interest, lp::NackReason::CONGESTION);
Teng Liang7003e0b2018-03-03 16:03:30 -0700388
ashiqopu075bb7d2019-03-10 01:38:21 +0000389 face1->receiveInterest(*interest, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700390 auto entry = pit.find(*interest);
ashiqopud3ae85d2019-02-17 02:29:55 +0000391 entry->insertOrUpdateOutRecord(*face2, 0, *interest);
392 entry->insertOrUpdateOutRecord(*face3, 0, *interest);
Teng Liang7003e0b2018-03-03 16:03:30 -0700393
394 //pitEntry is not erased after receiving the first Nack
395 this->advanceClocks(10_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000396 face2->receiveNack(nack, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700397 this->advanceClocks(1_ms);
398 BOOST_CHECK_EQUAL(pit.size(), 1);
399
400 //pitEntry is erased after receiving the second Nack
401 this->advanceClocks(10_ms);
ashiqopu075bb7d2019-03-10 01:38:21 +0000402 face3->receiveNack(nack, 0);
Teng Liang7003e0b2018-03-03 16:03:30 -0700403 this->advanceClocks(1_ms);
404 BOOST_CHECK_EQUAL(pit.size(), 0);
405}
406
407BOOST_AUTO_TEST_SUITE_END() // TestPitExpiry
408BOOST_AUTO_TEST_SUITE_END() // Fw
409
410} // namespace tests
411} // namespace fw
412} // namespace nfd