blob: 1977458526f89877e2843df96871b89250f09c0a [file] [log] [blame]
Teng Liang7003e0b2018-03-03 16:03:30 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2018, Regents of the University of California,
4 * 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
26#include "dummy-strategy.hpp"
27#include "choose-strategy.hpp"
28#include "tests/daemon/face/dummy-face.hpp"
29
30#include "tests/test-common.hpp"
31
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)
41BOOST_FIXTURE_TEST_SUITE(TestPitExpiry, UnitTestTimeFixture)
42
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
65 afterReceiveInterest(const Face& inFace, const Interest& interest,
66 const shared_ptr<pit::Entry>& pitEntry) override
67 {
Teng Liang85a36632018-03-21 05:59:34 -070068 DummyStrategy::afterReceiveInterest(inFace, 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,
77 const Face& inFace, const Data& data) override
78 {
Teng Liang85a36632018-03-21 05:59:34 -070079 DummyStrategy::beforeSatisfyInterest(pitEntry, inFace, data);
Teng Liang7003e0b2018-03-03 16:03:30 -070080
Teng Liang85a36632018-03-21 05:59:34 -070081 if (beforeSatisfyInterest_count <= 1) {
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,
88 const Face& inFace, const Data& data) override
89 {
90 if (afterContentStoreHit_count == 0) {
91 setExpiryTimer(pitEntry, 190_ms);
92 }
93
94 DummyStrategy::afterContentStoreHit(pitEntry, inFace, data);
95 }
96
97 void
Teng Liang7003e0b2018-03-03 16:03:30 -070098 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
99 const shared_ptr<pit::Entry>& pitEntry) override
100 {
Teng Liang85a36632018-03-21 05:59:34 -0700101 DummyStrategy::afterReceiveNack(inFace, nack, pitEntry);
Teng Liang7003e0b2018-03-03 16:03:30 -0700102
103 if (afterReceiveNack_count <= 1) {
104 setExpiryTimer(pitEntry, 50_ms);
105 }
106 }
107};
108
109BOOST_AUTO_TEST_CASE(UnsatisfiedInterest)
110{
111 Forwarder forwarder;
112
113 auto face1 = make_shared<DummyFace>();
114 auto face2 = make_shared<DummyFace>();
115 forwarder.addFace(face1);
116 forwarder.addFace(face2);
117
118 Pit& pit = forwarder.getPit();
119
120 shared_ptr<Interest> interest1 = makeInterest("/A/0");
121 shared_ptr<Interest> interest2 = makeInterest("/A/1");
122 interest1->setInterestLifetime(90_ms);
123 interest2->setInterestLifetime(90_ms);
124
125 face1->receiveInterest(*interest1);
126 face2->receiveInterest(*interest2);
127 BOOST_CHECK_EQUAL(pit.size(), 2);
128
129 this->advanceClocks(100_ms);
130 BOOST_CHECK_EQUAL(pit.size(), 0);
131}
132
133BOOST_AUTO_TEST_CASE(SatisfiedInterest)
134{
135 Forwarder forwarder;
136
137 auto face1 = make_shared<DummyFace>();
138 auto face2 = make_shared<DummyFace>();
139 forwarder.addFace(face1);
140 forwarder.addFace(face2);
141
142 Pit& pit = forwarder.getPit();
143
144 shared_ptr<Interest> interest = makeInterest("/A/0");
145 interest->setInterestLifetime(90_ms);
146 shared_ptr<Data> data = makeData("/A/0");
147
148 face1->receiveInterest(*interest);
149
150 this->advanceClocks(30_ms);
151 face2->receiveData(*data);
152
153 this->advanceClocks(1_ms);
154 BOOST_CHECK_EQUAL(pit.size(), 0);
155}
156
Teng Liang85a36632018-03-21 05:59:34 -0700157BOOST_AUTO_TEST_CASE(CsHit)
158{
159 Forwarder forwarder;
160
161 auto face1 = make_shared<DummyFace>();
162 auto face2 = make_shared<DummyFace>();
163 forwarder.addFace(face1);
164 forwarder.addFace(face2);
165
166 Name strategyA("/strategyA/%FD%01");
167 PitExpiryTestStrategy::registerAs(strategyA);
168 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
169
170 shared_ptr<Interest> interest = makeInterest("/A/0");
171 interest->setInterestLifetime(90_ms);
172
173 shared_ptr<Data> data = makeData("/A/0");
174 data->setTag(make_shared<lp::IncomingFaceIdTag>(face2->getId()));
175
176 Pit& pit = forwarder.getPit();
177 BOOST_CHECK_EQUAL(pit.size(), 0);
178
179 Cs& cs = forwarder.getCs();
180 cs.insert(*data);
181
182 face1->receiveInterest(*interest);
183 this->advanceClocks(1_ms);
184 BOOST_CHECK_EQUAL(pit.size(), 1);
185
186 this->advanceClocks(190_ms);
187 BOOST_CHECK_EQUAL(pit.size(), 0);
188
189 face1->receiveInterest(*interest);
190 this->advanceClocks(1_ms);
191 BOOST_CHECK_EQUAL(pit.size(), 0);
192}
193
Teng Liang7003e0b2018-03-03 16:03:30 -0700194BOOST_AUTO_TEST_CASE(ReceiveNack)
195{
196 Forwarder forwarder;
197
198 auto face1 = make_shared<DummyFace>();
199 auto face2 = make_shared<DummyFace>();
200 auto face3 = make_shared<DummyFace>();
201 forwarder.addFace(face1);
202 forwarder.addFace(face2);
203 forwarder.addFace(face3);
204
205 Name strategyA("/strategyA/%FD%01");
206 PitExpiryTestStrategy::registerAs(strategyA);
207 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
208
209 Pit& pit = forwarder.getPit();
210
211 shared_ptr<Interest> interest = makeInterest("/A/0", 562);
212 interest->setInterestLifetime(90_ms);
213 lp::Nack nack = makeNack("/A/0", 562, lp::NackReason::CONGESTION);
214
215 face1->receiveInterest(*interest);
216 auto entry = pit.find(*interest);
217 entry->insertOrUpdateOutRecord(*face2, *interest);
218 entry->insertOrUpdateOutRecord(*face3, *interest);
219
220 this->advanceClocks(10_ms);
221 face2->receiveNack(nack);
222
223 this->advanceClocks(1_ms);
224 BOOST_CHECK_EQUAL(pit.size(), 1);
225
226 this->advanceClocks(50_ms);
227 BOOST_CHECK_EQUAL(pit.size(), 0);
228}
229
230BOOST_AUTO_TEST_CASE(ResetTimerAfterReceiveInterest)
231{
232 Forwarder forwarder;
233
234 auto face = make_shared<DummyFace>();
235 forwarder.addFace(face);
236
237 Name strategyA("/strategyA/%FD%01");
238 PitExpiryTestStrategy::registerAs(strategyA);
239 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
240
241 Pit& pit = forwarder.getPit();
242
243 shared_ptr<Interest> interest = makeInterest("/A/0");
244 interest->setInterestLifetime(90_ms);
245
246 face->receiveInterest(*interest);
247 BOOST_CHECK_EQUAL(pit.size(), 1);
248
249 this->advanceClocks(100_ms);
250 BOOST_CHECK_EQUAL(pit.size(), 1);
251
252 this->advanceClocks(100_ms);
253 BOOST_CHECK_EQUAL(pit.size(), 0);
254}
255
256BOOST_AUTO_TEST_CASE(ResetTimerBeforeSatisfyInterest)
257{
258 Forwarder forwarder;
259
260 auto face1 = make_shared<DummyFace>();
261 auto face2 = make_shared<DummyFace>();
262 forwarder.addFace(face1);
263 forwarder.addFace(face2);
264
265 Name strategyA("/strategyA/%FD%01");
266 PitExpiryTestStrategy::registerAs(strategyA);
267 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
268
269 Pit& pit = forwarder.getPit();
270
271 shared_ptr<Interest> interest = makeInterest("/A/0");
272 interest->setInterestLifetime(90_ms);
273 shared_ptr<Data> data = makeData("/A/0");
274
275 face1->receiveInterest(*interest);
276
277 this->advanceClocks(30_ms);
278 face2->receiveData(*data);
279
280 this->advanceClocks(1_ms);
281 BOOST_CHECK_EQUAL(pit.size(), 1);
282
283 this->advanceClocks(30_ms);
284 face2->receiveData(*data);
285
286 this->advanceClocks(1_ms);
287 BOOST_CHECK_EQUAL(pit.size(), 0);
288}
289
290BOOST_AUTO_TEST_CASE(ReceiveNackAfterResetTimer)
291{
292 Forwarder forwarder;
293
294 auto face1 = make_shared<DummyFace>();
295 auto face2 = make_shared<DummyFace>();
296 auto face3 = make_shared<DummyFace>();
297 forwarder.addFace(face1);
298 forwarder.addFace(face2);
299 forwarder.addFace(face3);
300
301 Name strategyA("/strategyA/%FD%01");
302 PitExpiryTestStrategy::registerAs(strategyA);
303 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
304
305 Pit& pit = forwarder.getPit();
306
307 shared_ptr<Interest> interest = makeInterest("/A/0", 562);
308 interest->setInterestLifetime(90_ms);
309 lp::Nack nack = makeNack("/A/0", 562, lp::NackReason::CONGESTION);
310
311 face1->receiveInterest(*interest);
312 auto entry = pit.find(*interest);
313 entry->insertOrUpdateOutRecord(*face2, *interest);
314 entry->insertOrUpdateOutRecord(*face3, *interest);
315
316 //pitEntry is not erased after receiving the first Nack
317 this->advanceClocks(10_ms);
318 face2->receiveNack(nack);
319 this->advanceClocks(1_ms);
320 BOOST_CHECK_EQUAL(pit.size(), 1);
321
322 //pitEntry is erased after receiving the second Nack
323 this->advanceClocks(10_ms);
324 face3->receiveNack(nack);
325 this->advanceClocks(1_ms);
326 BOOST_CHECK_EQUAL(pit.size(), 0);
327}
328
329BOOST_AUTO_TEST_SUITE_END() // TestPitExpiry
330BOOST_AUTO_TEST_SUITE_END() // Fw
331
332} // namespace tests
333} // namespace fw
334} // namespace nfd