blob: 4eacd9ec2a4a058fd37428522296d1b682d8b7b9 [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
32namespace nfd {
33namespace fw {
34namespace tests {
35
36using namespace nfd::tests;
37
38BOOST_AUTO_TEST_SUITE(Fw)
39BOOST_FIXTURE_TEST_SUITE(TestPitExpiry, UnitTestTimeFixture)
40
41class PitExpiryTestStrategy : public DummyStrategy
42{
43public:
44 static Name
45 getStrategyName(uint64_t version)
46 {
47 return Name("/PitExpiryTestStrategy").appendVersion(version);
48 }
49
50 static void
51 registerAs(const Name& strategyName)
52 {
53 registerAsImpl<PitExpiryTestStrategy>(strategyName);
54 }
55
56 explicit
57 PitExpiryTestStrategy(Forwarder& forwarder, const Name& name = getStrategyName(1))
58 : DummyStrategy(forwarder, name)
59 {
60 }
61
62 void
63 afterReceiveInterest(const Face& inFace, const Interest& interest,
64 const shared_ptr<pit::Entry>& pitEntry) override
65 {
66 ++afterReceiveInterest_count;
67
68 if (afterReceiveInterest_count <= 1) {
69 setExpiryTimer(pitEntry, 190_ms);
70 }
71 }
72
73 void
74 beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
75 const Face& inFace, const Data& data) override
76 {
77 ++beforeSatisfyInterest_count;
78
79 if (beforeSatisfyInterest_count <= 1 ) {
80 setExpiryTimer(pitEntry, 190_ms);
81 }
82 }
83
84 void
85 afterReceiveNack(const Face& inFace, const lp::Nack& nack,
86 const shared_ptr<pit::Entry>& pitEntry) override
87 {
88 ++afterReceiveNack_count;
89
90 if (afterReceiveNack_count <= 1) {
91 setExpiryTimer(pitEntry, 50_ms);
92 }
93 }
94};
95
96BOOST_AUTO_TEST_CASE(UnsatisfiedInterest)
97{
98 Forwarder forwarder;
99
100 auto face1 = make_shared<DummyFace>();
101 auto face2 = make_shared<DummyFace>();
102 forwarder.addFace(face1);
103 forwarder.addFace(face2);
104
105 Pit& pit = forwarder.getPit();
106
107 shared_ptr<Interest> interest1 = makeInterest("/A/0");
108 shared_ptr<Interest> interest2 = makeInterest("/A/1");
109 interest1->setInterestLifetime(90_ms);
110 interest2->setInterestLifetime(90_ms);
111
112 face1->receiveInterest(*interest1);
113 face2->receiveInterest(*interest2);
114 BOOST_CHECK_EQUAL(pit.size(), 2);
115
116 this->advanceClocks(100_ms);
117 BOOST_CHECK_EQUAL(pit.size(), 0);
118}
119
120BOOST_AUTO_TEST_CASE(SatisfiedInterest)
121{
122 Forwarder forwarder;
123
124 auto face1 = make_shared<DummyFace>();
125 auto face2 = make_shared<DummyFace>();
126 forwarder.addFace(face1);
127 forwarder.addFace(face2);
128
129 Pit& pit = forwarder.getPit();
130
131 shared_ptr<Interest> interest = makeInterest("/A/0");
132 interest->setInterestLifetime(90_ms);
133 shared_ptr<Data> data = makeData("/A/0");
134
135 face1->receiveInterest(*interest);
136
137 this->advanceClocks(30_ms);
138 face2->receiveData(*data);
139
140 this->advanceClocks(1_ms);
141 BOOST_CHECK_EQUAL(pit.size(), 0);
142}
143
144BOOST_AUTO_TEST_CASE(ReceiveNack)
145{
146 Forwarder forwarder;
147
148 auto face1 = make_shared<DummyFace>();
149 auto face2 = make_shared<DummyFace>();
150 auto face3 = make_shared<DummyFace>();
151 forwarder.addFace(face1);
152 forwarder.addFace(face2);
153 forwarder.addFace(face3);
154
155 Name strategyA("/strategyA/%FD%01");
156 PitExpiryTestStrategy::registerAs(strategyA);
157 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
158
159 Pit& pit = forwarder.getPit();
160
161 shared_ptr<Interest> interest = makeInterest("/A/0", 562);
162 interest->setInterestLifetime(90_ms);
163 lp::Nack nack = makeNack("/A/0", 562, lp::NackReason::CONGESTION);
164
165 face1->receiveInterest(*interest);
166 auto entry = pit.find(*interest);
167 entry->insertOrUpdateOutRecord(*face2, *interest);
168 entry->insertOrUpdateOutRecord(*face3, *interest);
169
170 this->advanceClocks(10_ms);
171 face2->receiveNack(nack);
172
173 this->advanceClocks(1_ms);
174 BOOST_CHECK_EQUAL(pit.size(), 1);
175
176 this->advanceClocks(50_ms);
177 BOOST_CHECK_EQUAL(pit.size(), 0);
178}
179
180BOOST_AUTO_TEST_CASE(ResetTimerAfterReceiveInterest)
181{
182 Forwarder forwarder;
183
184 auto face = make_shared<DummyFace>();
185 forwarder.addFace(face);
186
187 Name strategyA("/strategyA/%FD%01");
188 PitExpiryTestStrategy::registerAs(strategyA);
189 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
190
191 Pit& pit = forwarder.getPit();
192
193 shared_ptr<Interest> interest = makeInterest("/A/0");
194 interest->setInterestLifetime(90_ms);
195
196 face->receiveInterest(*interest);
197 BOOST_CHECK_EQUAL(pit.size(), 1);
198
199 this->advanceClocks(100_ms);
200 BOOST_CHECK_EQUAL(pit.size(), 1);
201
202 this->advanceClocks(100_ms);
203 BOOST_CHECK_EQUAL(pit.size(), 0);
204}
205
206BOOST_AUTO_TEST_CASE(ResetTimerBeforeSatisfyInterest)
207{
208 Forwarder forwarder;
209
210 auto face1 = make_shared<DummyFace>();
211 auto face2 = make_shared<DummyFace>();
212 forwarder.addFace(face1);
213 forwarder.addFace(face2);
214
215 Name strategyA("/strategyA/%FD%01");
216 PitExpiryTestStrategy::registerAs(strategyA);
217 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
218
219 Pit& pit = forwarder.getPit();
220
221 shared_ptr<Interest> interest = makeInterest("/A/0");
222 interest->setInterestLifetime(90_ms);
223 shared_ptr<Data> data = makeData("/A/0");
224
225 face1->receiveInterest(*interest);
226
227 this->advanceClocks(30_ms);
228 face2->receiveData(*data);
229
230 this->advanceClocks(1_ms);
231 BOOST_CHECK_EQUAL(pit.size(), 1);
232
233 this->advanceClocks(30_ms);
234 face2->receiveData(*data);
235
236 this->advanceClocks(1_ms);
237 BOOST_CHECK_EQUAL(pit.size(), 0);
238}
239
240BOOST_AUTO_TEST_CASE(ReceiveNackAfterResetTimer)
241{
242 Forwarder forwarder;
243
244 auto face1 = make_shared<DummyFace>();
245 auto face2 = make_shared<DummyFace>();
246 auto face3 = make_shared<DummyFace>();
247 forwarder.addFace(face1);
248 forwarder.addFace(face2);
249 forwarder.addFace(face3);
250
251 Name strategyA("/strategyA/%FD%01");
252 PitExpiryTestStrategy::registerAs(strategyA);
253 choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
254
255 Pit& pit = forwarder.getPit();
256
257 shared_ptr<Interest> interest = makeInterest("/A/0", 562);
258 interest->setInterestLifetime(90_ms);
259 lp::Nack nack = makeNack("/A/0", 562, lp::NackReason::CONGESTION);
260
261 face1->receiveInterest(*interest);
262 auto entry = pit.find(*interest);
263 entry->insertOrUpdateOutRecord(*face2, *interest);
264 entry->insertOrUpdateOutRecord(*face3, *interest);
265
266 //pitEntry is not erased after receiving the first Nack
267 this->advanceClocks(10_ms);
268 face2->receiveNack(nack);
269 this->advanceClocks(1_ms);
270 BOOST_CHECK_EQUAL(pit.size(), 1);
271
272 //pitEntry is erased after receiving the second Nack
273 this->advanceClocks(10_ms);
274 face3->receiveNack(nack);
275 this->advanceClocks(1_ms);
276 BOOST_CHECK_EQUAL(pit.size(), 0);
277}
278
279BOOST_AUTO_TEST_SUITE_END() // TestPitExpiry
280BOOST_AUTO_TEST_SUITE_END() // Fw
281
282} // namespace tests
283} // namespace fw
284} // namespace nfd