blob: 1b74f37eb1f84fe9eca46bda3713ae1976d010f7 [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi82e7f582014-09-07 15:15:40 -07003 * Copyright (c) 2014, 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
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shi82e7f582014-09-07 15:15:40 -070024 */
Junxiao Shi8c8d2182014-01-30 22:33:00 -070025
26#include "fw/forwarder.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070027#include "tests/daemon/face/dummy-face.hpp"
Junxiao Shif3c07812014-03-11 21:48:49 -070028#include "dummy-strategy.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070029
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070031#include "tests/limited-io.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070032
33namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070034namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070035
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036BOOST_FIXTURE_TEST_SUITE(FwForwarder, BaseFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070037
Junxiao Shi8c8d2182014-01-30 22:33:00 -070038BOOST_AUTO_TEST_CASE(SimpleExchange)
39{
Junxiao Shi75ab6b72014-11-30 01:01:05 -070040 LimitedIo limitedIo;
41 auto afterOp = bind(&LimitedIo::afterOp, &limitedIo);;
Junxiao Shic041ca32014-02-25 20:01:15 -070042 Forwarder forwarder;
43
Junxiao Shi8c8d2182014-01-30 22:33:00 -070044 Name nameA ("ndn:/A");
45 Name nameAB ("ndn:/A/B");
46 Name nameABC("ndn:/A/B/C");
Junxiao Shif3c07812014-03-11 21:48:49 -070047 shared_ptr<Interest> interestAB = makeInterest(nameAB);
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070048 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shif3c07812014-03-11 21:48:49 -070049 shared_ptr<Data> dataABC = makeData(nameABC);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070050
Junxiao Shid9ee45c2014-02-27 15:38:11 -070051 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
52 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
Junxiao Shi75ab6b72014-11-30 01:01:05 -070053 face1->afterSend += afterOp;
54 face2->afterSend += afterOp;
Junxiao Shi8c8d2182014-01-30 22:33:00 -070055 forwarder.addFace(face1);
56 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070057
Junxiao Shi8c8d2182014-01-30 22:33:00 -070058 Fib& fib = forwarder.getFib();
Junxiao Shi6e694322014-04-03 10:27:13 -070059 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
Junxiao Shi8c8d2182014-01-30 22:33:00 -070060 fibEntry->addNextHop(face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070061
Junxiao Shi6e694322014-04-03 10:27:13 -070062 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 0);
63 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070064 g_io.post([&] { face1->receiveInterest(*interestAB); });
65 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070066 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070067 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getName(), nameAB);
Junxiao Shi06887ac2014-02-13 20:15:42 -070068 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070069 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 1);
70 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070071
Junxiao Shi6e694322014-04-03 10:27:13 -070072 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 0);
73 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070074 g_io.post([&] { face2->receiveData(*dataABC); });
75 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070076 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070077 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getName(), nameABC);
Junxiao Shi06887ac2014-02-13 20:15:42 -070078 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070079 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 1);
80 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070081}
82
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070083BOOST_AUTO_TEST_CASE(CsMatched)
84{
85 LimitedIo limitedIo;
86 Forwarder forwarder;
87
88 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
89 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
90 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
91 forwarder.addFace(face1);
92 forwarder.addFace(face2);
93 forwarder.addFace(face3);
94
95 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
96 interestA->setInterestLifetime(time::seconds(4));
97 shared_ptr<Data> dataA = makeData("ndn:/A");
98 dataA->setIncomingFaceId(face3->getId());
99
100 Fib& fib = forwarder.getFib();
101 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
102 fibEntry->addNextHop(face2, 0);
103
104 Pit& pit = forwarder.getPit();
105 BOOST_CHECK_EQUAL(pit.size(), 0);
106
107 Cs& cs = forwarder.getCs();
108 BOOST_REQUIRE(cs.insert(*dataA));
109
110 face1->receiveInterest(*interestA);
111 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
112 // Interest matching ContentStore should not be forwarded
113 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 0);
114
115 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
116 // IncomingFaceId field should be reset to represent CS
117 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), FACEID_CONTENT_STORE);
118
119 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
120 // PIT entry should not be left behind
121 BOOST_CHECK_EQUAL(pit.size(), 0);
122}
123
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700124class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700125{
126public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700127 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700128 {
129 }
130
131 virtual void
132 onDataUnsolicited(Face& inFace, const Data& data)
133 {
134 ++m_onDataUnsolicited_count;
135 }
136
137protected:
138 virtual void
Junxiao Shif3c07812014-03-11 21:48:49 -0700139 dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f)
Junxiao Shi88884492014-02-15 15:57:43 -0700140 {
141 ++m_dispatchToStrategy_count;
142 }
143
144public:
145 int m_dispatchToStrategy_count;
146 int m_onDataUnsolicited_count;
147};
148
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700149BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700150{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700151 ScopeLocalhostIncomingTestForwarder forwarder;
152 shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
153 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700154 forwarder.addFace(face1);
155 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700156
Junxiao Shi88884492014-02-15 15:57:43 -0700157 // local face, /localhost: OK
158 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700159 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800160 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi88884492014-02-15 15:57:43 -0700161 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700162
Junxiao Shi88884492014-02-15 15:57:43 -0700163 // non-local face, /localhost: violate
164 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700165 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800166 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi88884492014-02-15 15:57:43 -0700167 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700168
Junxiao Shi88884492014-02-15 15:57:43 -0700169 // local face, non-/localhost: OK
170 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700171 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800172 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi88884492014-02-15 15:57:43 -0700173 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700174
Junxiao Shi88884492014-02-15 15:57:43 -0700175 // non-local face, non-/localhost: OK
176 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700177 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800178 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi88884492014-02-15 15:57:43 -0700179 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700180
Junxiao Shi88884492014-02-15 15:57:43 -0700181 // local face, /localhost: OK
182 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700183 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800184 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi88884492014-02-15 15:57:43 -0700185 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
186
187 // non-local face, /localhost: OK
188 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700189 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800190 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi88884492014-02-15 15:57:43 -0700191 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700192
Junxiao Shi88884492014-02-15 15:57:43 -0700193 // local face, non-/localhost: OK
194 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700195 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800196 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi88884492014-02-15 15:57:43 -0700197 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
198
199 // non-local face, non-/localhost: OK
200 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700201 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800202 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi88884492014-02-15 15:57:43 -0700203 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
204}
205
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700206BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
207{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700208 Forwarder forwarder;
209 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
210 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
211 shared_ptr<Face> face3 = make_shared<DummyLocalFace>();
212 forwarder.addFace(face1);
213 forwarder.addFace(face2);
214 forwarder.addFace(face3);
215 Pit& pit = forwarder.getPit();
216
217 // local face, /localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700218 shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
219 shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
220 pitA1->insertOrUpdateInRecord(face3, *interestA1);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700221 face1->m_sentInterests.clear();
222 forwarder.onOutgoingInterest(pitA1, *face1);
223 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
224
225 // non-local face, /localhost: violate
Junxiao Shif3c07812014-03-11 21:48:49 -0700226 shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
227 shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
228 pitA2->insertOrUpdateInRecord(face3, *interestA2);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700229 face2->m_sentInterests.clear();
230 forwarder.onOutgoingInterest(pitA2, *face2);
231 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
232
233 // local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700234 shared_ptr<Interest> interestA3 = makeInterest("/A3");
235 shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
236 pitA3->insertOrUpdateInRecord(face3, *interestA3);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700237 face1->m_sentInterests.clear();
238 forwarder.onOutgoingInterest(pitA3, *face1);
239 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
240
241 // non-local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700242 shared_ptr<Interest> interestA4 = makeInterest("/A4");
243 shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
244 pitA4->insertOrUpdateInRecord(face3, *interestA4);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700245 face2->m_sentInterests.clear();
246 forwarder.onOutgoingInterest(pitA4, *face2);
247 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
248
249 // local face, /localhost: OK
250 face1->m_sentDatas.clear();
251 forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
252 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
253
254 // non-local face, /localhost: OK
255 face2->m_sentDatas.clear();
256 forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
257 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
258
259 // local face, non-/localhost: OK
260 face1->m_sentDatas.clear();
261 forwarder.onOutgoingData(Data("/B3"), *face1);
262 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
263
264 // non-local face, non-/localhost: OK
265 face2->m_sentDatas.clear();
266 forwarder.onOutgoingData(Data("/B4"), *face2);
267 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
268}
269
Junxiao Shi11bd9c22014-03-13 20:44:13 -0700270BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
271{
272 Forwarder forwarder;
273 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
274 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
275 shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
276 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
277 forwarder.addFace(face1);
278 forwarder.addFace(face2);
279 forwarder.addFace(face3);
280 forwarder.addFace(face4);
281 Pit& pit = forwarder.getPit();
282
283 // from local face, to local face: OK
284 shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
285 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
286 pit1->insertOrUpdateInRecord(face1, *interest1);
287 face3->m_sentInterests.clear();
288 forwarder.onOutgoingInterest(pit1, *face3);
289 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
290
291 // from non-local face, to local face: OK
292 shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
293 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
294 pit2->insertOrUpdateInRecord(face2, *interest2);
295 face3->m_sentInterests.clear();
296 forwarder.onOutgoingInterest(pit2, *face3);
297 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
298
299 // from local face, to non-local face: OK
300 shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
301 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
302 pit3->insertOrUpdateInRecord(face1, *interest3);
303 face4->m_sentInterests.clear();
304 forwarder.onOutgoingInterest(pit3, *face4);
305 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
306
307 // from non-local face, to non-local face: violate
308 shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
309 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
310 pit4->insertOrUpdateInRecord(face2, *interest4);
311 face4->m_sentInterests.clear();
312 forwarder.onOutgoingInterest(pit4, *face4);
313 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
314
315 // from local face and non-local face, to local face: OK
316 shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
317 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
318 pit5->insertOrUpdateInRecord(face1, *interest5);
319 pit5->insertOrUpdateInRecord(face2, *interest5);
320 face3->m_sentInterests.clear();
321 forwarder.onOutgoingInterest(pit5, *face3);
322 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
323
324 // from local face and non-local face, to non-local face: OK
325 shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
326 shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
327 pit6->insertOrUpdateInRecord(face1, *interest6);
328 pit6->insertOrUpdateInRecord(face2, *interest6);
329 face4->m_sentInterests.clear();
330 forwarder.onOutgoingInterest(pit6, *face4);
331 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
332}
333
Junxiao Shif3c07812014-03-11 21:48:49 -0700334BOOST_AUTO_TEST_CASE(StrategyDispatch)
335{
336 LimitedIo limitedIo;
337 Forwarder forwarder;
338 shared_ptr<Face> face1 = make_shared<DummyFace>();
339 shared_ptr<Face> face2 = make_shared<DummyFace>();
340 forwarder.addFace(face1);
341 forwarder.addFace(face2);
342
343 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
344 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700345 ref(forwarder), "ndn:/strategyP");
Junxiao Shif3c07812014-03-11 21:48:49 -0700346 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700347 ref(forwarder), "ndn:/strategyQ");
Junxiao Shif3c07812014-03-11 21:48:49 -0700348 strategyChoice.install(strategyP);
349 strategyChoice.install(strategyQ);
350 strategyChoice.insert("ndn:/" , strategyP->getName());
351 strategyChoice.insert("ndn:/B", strategyQ->getName());
352
353 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
354 strategyP->m_afterReceiveInterest_count = 0;
355 strategyP->m_interestOutFace = face2;
356 forwarder.onInterest(*face1, *interest1);
357 BOOST_CHECK_EQUAL(strategyP->m_afterReceiveInterest_count, 1);
358
359 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
360 strategyQ->m_afterReceiveInterest_count = 0;
361 strategyQ->m_interestOutFace = face2;
362 forwarder.onInterest(*face1, *interest2);
363 BOOST_CHECK_EQUAL(strategyQ->m_afterReceiveInterest_count, 1);
364
365 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
366
367 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi82e7f582014-09-07 15:15:40 -0700368 strategyP->m_beforeSatisfyInterest_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700369 forwarder.onData(*face2, *data1);
Junxiao Shi82e7f582014-09-07 15:15:40 -0700370 BOOST_CHECK_EQUAL(strategyP->m_beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700371
372 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi82e7f582014-09-07 15:15:40 -0700373 strategyQ->m_beforeSatisfyInterest_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700374 forwarder.onData(*face2, *data2);
Junxiao Shi82e7f582014-09-07 15:15:40 -0700375 BOOST_CHECK_EQUAL(strategyQ->m_beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700376
377 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700378 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shif3c07812014-03-11 21:48:49 -0700379 forwarder.onInterest(*face1, *interest3);
380 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700381 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shif3c07812014-03-11 21:48:49 -0700382 forwarder.onInterest(*face1, *interest4);
383
384 strategyP->m_beforeExpirePendingInterest_count = 0;
385 strategyQ->m_beforeExpirePendingInterest_count = 0;
386 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
387 BOOST_CHECK_EQUAL(strategyP->m_beforeExpirePendingInterest_count, 1);
388 BOOST_CHECK_EQUAL(strategyQ->m_beforeExpirePendingInterest_count, 0);
389}
390
Junxiao Shida006f52014-05-16 11:18:00 -0700391BOOST_AUTO_TEST_CASE(IncomingData)
392{
393 LimitedIo limitedIo;
394 Forwarder forwarder;
395 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
396 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
397 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
398 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
399 forwarder.addFace(face1);
400 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700401 forwarder.addFace(face3);
402 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700403
404 Pit& pit = forwarder.getPit();
405 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
406 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
407 pit0->insertOrUpdateInRecord(face1, *interest0);
408 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
409 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
410 pitA->insertOrUpdateInRecord(face1, *interestA);
411 pitA->insertOrUpdateInRecord(face2, *interestA);
412 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
413 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
414 pitC->insertOrUpdateInRecord(face3, *interestC);
415 pitC->insertOrUpdateInRecord(face4, *interestC);
416
417 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
418 forwarder.onIncomingData(*face3, *dataD);
419 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
420
421 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
422 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
423 BOOST_CHECK_EQUAL(face3->m_sentDatas.size(), 0);
424 BOOST_CHECK_EQUAL(face4->m_sentDatas.size(), 1);
425}
426
Junxiao Shi455581d2014-11-17 18:38:40 -0700427BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700428{
Junxiao Shia110f262014-10-12 12:35:20 -0700429 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700430 auto face1 = make_shared<DummyFace>();
431 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700432 forwarder.addFace(face1);
433 forwarder.addFace(face2);
434
435 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shi455581d2014-11-17 18:38:40 -0700436 face2->onSendInterest += [&face1] (const Interest& interest) {
437 scheduler::schedule(time::milliseconds(170), [&] { face1->receiveInterest(interest); });
438 };
Junxiao Shia110f262014-10-12 12:35:20 -0700439
440 Fib& fib = forwarder.getFib();
441 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
442 fibEntry->addNextHop(face2, 0);
443
Junxiao Shi455581d2014-11-17 18:38:40 -0700444 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700445 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
446 interest->setNonce(82101183);
447 interest->setInterestLifetime(time::milliseconds(50));
448 face1->receiveInterest(*interest);
449
Junxiao Shi455581d2014-11-17 18:38:40 -0700450 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
451 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
452 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700453
454 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700455
456 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
457 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
458 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
459 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
460 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700461}
462
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700463BOOST_AUTO_TEST_SUITE_END()
464
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700465} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700466} // namespace nfd