blob: 6a3509f6950fb8dc3163d1fbca023800d9033aa9 [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08003 * Copyright (c) 2014-2015, 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 Shi5e5e4452015-09-24 16:56:52 -070028#include "tests/daemon/face/dummy-lp-face.hpp"
29#include "face/lp-face-wrapper.hpp"
Junxiao Shif3c07812014-03-11 21:48:49 -070030#include "dummy-strategy.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070031
Junxiao Shid9ee45c2014-02-27 15:38:11 -070032#include "tests/test-common.hpp"
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070033#include "tests/limited-io.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070034
35namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070037
Junxiao Shi0355e9f2015-09-02 07:24:53 -070038BOOST_AUTO_TEST_SUITE(Fw)
39BOOST_FIXTURE_TEST_SUITE(TestForwarder, BaseFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070040
Junxiao Shi8c8d2182014-01-30 22:33:00 -070041BOOST_AUTO_TEST_CASE(SimpleExchange)
42{
Junxiao Shi75ab6b72014-11-30 01:01:05 -070043 LimitedIo limitedIo;
44 auto afterOp = bind(&LimitedIo::afterOp, &limitedIo);;
Junxiao Shic041ca32014-02-25 20:01:15 -070045 Forwarder forwarder;
46
Junxiao Shi8c8d2182014-01-30 22:33:00 -070047 Name nameA ("ndn:/A");
48 Name nameAB ("ndn:/A/B");
49 Name nameABC("ndn:/A/B/C");
Junxiao Shif3c07812014-03-11 21:48:49 -070050 shared_ptr<Interest> interestAB = makeInterest(nameAB);
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070051 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shif3c07812014-03-11 21:48:49 -070052 shared_ptr<Data> dataABC = makeData(nameABC);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070053
Junxiao Shid9ee45c2014-02-27 15:38:11 -070054 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
55 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
Junxiao Shic099ddb2014-12-25 20:53:20 -070056 face1->afterSend.connect(afterOp);
57 face2->afterSend.connect(afterOp);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070058 forwarder.addFace(face1);
59 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070060
Junxiao Shi8c8d2182014-01-30 22:33:00 -070061 Fib& fib = forwarder.getFib();
Junxiao Shi6e694322014-04-03 10:27:13 -070062 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
Junxiao Shi8c8d2182014-01-30 22:33:00 -070063 fibEntry->addNextHop(face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070064
Junxiao Shi6e694322014-04-03 10:27:13 -070065 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 0);
66 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070067 g_io.post([&] { face1->receiveInterest(*interestAB); });
68 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070069 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070070 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getName(), nameAB);
Junxiao Shi06887ac2014-02-13 20:15:42 -070071 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070072 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 1);
73 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070074
Junxiao Shi6e694322014-04-03 10:27:13 -070075 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 0);
76 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 0);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070077 g_io.post([&] { face2->receiveData(*dataABC); });
78 BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070079 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
Junxiao Shi75ab6b72014-11-30 01:01:05 -070080 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getName(), nameABC);
Junxiao Shi06887ac2014-02-13 20:15:42 -070081 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070082 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 1);
83 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070084}
85
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070086BOOST_AUTO_TEST_CASE(CsMatched)
87{
88 LimitedIo limitedIo;
89 Forwarder forwarder;
90
91 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
92 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
93 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
94 forwarder.addFace(face1);
95 forwarder.addFace(face2);
96 forwarder.addFace(face3);
97
98 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
99 interestA->setInterestLifetime(time::seconds(4));
100 shared_ptr<Data> dataA = makeData("ndn:/A");
101 dataA->setIncomingFaceId(face3->getId());
102
103 Fib& fib = forwarder.getFib();
104 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
105 fibEntry->addNextHop(face2, 0);
106
107 Pit& pit = forwarder.getPit();
108 BOOST_CHECK_EQUAL(pit.size(), 0);
109
110 Cs& cs = forwarder.getCs();
111 BOOST_REQUIRE(cs.insert(*dataA));
112
113 face1->receiveInterest(*interestA);
114 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
115 // Interest matching ContentStore should not be forwarded
116 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 0);
117
118 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
119 // IncomingFaceId field should be reset to represent CS
120 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), FACEID_CONTENT_STORE);
121
122 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
123 // PIT entry should not be left behind
124 BOOST_CHECK_EQUAL(pit.size(), 0);
125}
126
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700127class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700128{
129public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700130 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700131 {
132 }
133
134 virtual void
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700135 onDataUnsolicited(Face& inFace, const Data& data) DECL_OVERRIDE
Junxiao Shi88884492014-02-15 15:57:43 -0700136 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700137 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700138 }
139
140protected:
141 virtual void
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700142 dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f) DECL_OVERRIDE
Junxiao Shi88884492014-02-15 15:57:43 -0700143 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700144 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700145 }
146
147public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700148 int dispatchToStrategy_count;
149 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700150};
151
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700152BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700153{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700154 ScopeLocalhostIncomingTestForwarder forwarder;
155 shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
156 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700157 forwarder.addFace(face1);
158 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700159
Junxiao Shi88884492014-02-15 15:57:43 -0700160 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700161 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700162 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800163 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700164 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700165
Junxiao Shi88884492014-02-15 15:57:43 -0700166 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700167 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700168 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800169 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700170 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700171
Junxiao Shi88884492014-02-15 15:57:43 -0700172 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700173 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700174 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800175 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700176 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700177
Junxiao Shi88884492014-02-15 15:57:43 -0700178 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700179 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700180 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800181 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700182 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700183
Junxiao Shi88884492014-02-15 15:57:43 -0700184 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700185 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700186 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800187 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700188 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700189
190 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700191 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700192 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800193 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700194 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700195
Junxiao Shi88884492014-02-15 15:57:43 -0700196 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700197 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700198 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800199 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700200 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700201
202 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700203 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700204 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800205 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700206 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700207}
208
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700209BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
210{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700211 Forwarder forwarder;
212 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
213 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
214 shared_ptr<Face> face3 = make_shared<DummyLocalFace>();
215 forwarder.addFace(face1);
216 forwarder.addFace(face2);
217 forwarder.addFace(face3);
218 Pit& pit = forwarder.getPit();
219
220 // local face, /localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700221 shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
222 shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
223 pitA1->insertOrUpdateInRecord(face3, *interestA1);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700224 face1->m_sentInterests.clear();
225 forwarder.onOutgoingInterest(pitA1, *face1);
226 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
227
228 // non-local face, /localhost: violate
Junxiao Shif3c07812014-03-11 21:48:49 -0700229 shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
230 shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
231 pitA2->insertOrUpdateInRecord(face3, *interestA2);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700232 face2->m_sentInterests.clear();
233 forwarder.onOutgoingInterest(pitA2, *face2);
234 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
235
236 // local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700237 shared_ptr<Interest> interestA3 = makeInterest("/A3");
238 shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
239 pitA3->insertOrUpdateInRecord(face3, *interestA3);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700240 face1->m_sentInterests.clear();
241 forwarder.onOutgoingInterest(pitA3, *face1);
242 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
243
244 // non-local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700245 shared_ptr<Interest> interestA4 = makeInterest("/A4");
246 shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
247 pitA4->insertOrUpdateInRecord(face3, *interestA4);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700248 face2->m_sentInterests.clear();
249 forwarder.onOutgoingInterest(pitA4, *face2);
250 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
251
252 // local face, /localhost: OK
253 face1->m_sentDatas.clear();
254 forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
255 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
256
257 // non-local face, /localhost: OK
258 face2->m_sentDatas.clear();
259 forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
260 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
261
262 // local face, non-/localhost: OK
263 face1->m_sentDatas.clear();
264 forwarder.onOutgoingData(Data("/B3"), *face1);
265 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
266
267 // non-local face, non-/localhost: OK
268 face2->m_sentDatas.clear();
269 forwarder.onOutgoingData(Data("/B4"), *face2);
270 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
271}
272
Junxiao Shi11bd9c22014-03-13 20:44:13 -0700273BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
274{
275 Forwarder forwarder;
276 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
277 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
278 shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
279 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
280 forwarder.addFace(face1);
281 forwarder.addFace(face2);
282 forwarder.addFace(face3);
283 forwarder.addFace(face4);
284 Pit& pit = forwarder.getPit();
285
286 // from local face, to local face: OK
287 shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
288 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
289 pit1->insertOrUpdateInRecord(face1, *interest1);
290 face3->m_sentInterests.clear();
291 forwarder.onOutgoingInterest(pit1, *face3);
292 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
293
294 // from non-local face, to local face: OK
295 shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
296 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
297 pit2->insertOrUpdateInRecord(face2, *interest2);
298 face3->m_sentInterests.clear();
299 forwarder.onOutgoingInterest(pit2, *face3);
300 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
301
302 // from local face, to non-local face: OK
303 shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
304 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
305 pit3->insertOrUpdateInRecord(face1, *interest3);
306 face4->m_sentInterests.clear();
307 forwarder.onOutgoingInterest(pit3, *face4);
308 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
309
310 // from non-local face, to non-local face: violate
311 shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
312 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
313 pit4->insertOrUpdateInRecord(face2, *interest4);
314 face4->m_sentInterests.clear();
315 forwarder.onOutgoingInterest(pit4, *face4);
316 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
317
318 // from local face and non-local face, to local face: OK
319 shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
320 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
321 pit5->insertOrUpdateInRecord(face1, *interest5);
322 pit5->insertOrUpdateInRecord(face2, *interest5);
323 face3->m_sentInterests.clear();
324 forwarder.onOutgoingInterest(pit5, *face3);
325 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
326
327 // from local face and non-local face, to non-local face: OK
328 shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
329 shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
330 pit6->insertOrUpdateInRecord(face1, *interest6);
331 pit6->insertOrUpdateInRecord(face2, *interest6);
332 face4->m_sentInterests.clear();
333 forwarder.onOutgoingInterest(pit6, *face4);
334 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
335}
336
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700337BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700338{
339 LimitedIo limitedIo;
340 Forwarder forwarder;
341 shared_ptr<Face> face1 = make_shared<DummyFace>();
342 shared_ptr<Face> face2 = make_shared<DummyFace>();
343 forwarder.addFace(face1);
344 forwarder.addFace(face2);
345
346 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
347 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700348 ref(forwarder), "ndn:/strategyP");
Junxiao Shif3c07812014-03-11 21:48:49 -0700349 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
Alexander Afanasyevf6980282014-05-13 18:28:40 -0700350 ref(forwarder), "ndn:/strategyQ");
Junxiao Shif3c07812014-03-11 21:48:49 -0700351 strategyChoice.install(strategyP);
352 strategyChoice.install(strategyQ);
353 strategyChoice.insert("ndn:/" , strategyP->getName());
354 strategyChoice.insert("ndn:/B", strategyQ->getName());
355
356 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700357 strategyP->afterReceiveInterest_count = 0;
358 strategyP->interestOutFace = face2;
359 forwarder.startProcessInterest(*face1, *interest1);
360 BOOST_CHECK_EQUAL(strategyP->afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700361
362 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700363 strategyQ->afterReceiveInterest_count = 0;
364 strategyQ->interestOutFace = face2;
365 forwarder.startProcessInterest(*face1, *interest2);
366 BOOST_CHECK_EQUAL(strategyQ->afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700367
368 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
369
370 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700371 strategyP->beforeSatisfyInterest_count = 0;
372 forwarder.startProcessData(*face2, *data1);
373 BOOST_CHECK_EQUAL(strategyP->beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700374
375 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700376 strategyQ->beforeSatisfyInterest_count = 0;
377 forwarder.startProcessData(*face2, *data2);
378 BOOST_CHECK_EQUAL(strategyQ->beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700379
380 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700381 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700382 forwarder.startProcessInterest(*face1, *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700383 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700384 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700385 forwarder.startProcessInterest(*face1, *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700386
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700387 strategyP->beforeExpirePendingInterest_count = 0;
388 strategyQ->beforeExpirePendingInterest_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700389 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700390 BOOST_CHECK_EQUAL(strategyP->beforeExpirePendingInterest_count, 1);
391 BOOST_CHECK_EQUAL(strategyQ->beforeExpirePendingInterest_count, 0);
Junxiao Shif3c07812014-03-11 21:48:49 -0700392}
393
Junxiao Shida006f52014-05-16 11:18:00 -0700394BOOST_AUTO_TEST_CASE(IncomingData)
395{
396 LimitedIo limitedIo;
397 Forwarder forwarder;
398 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
399 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
400 shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
401 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
402 forwarder.addFace(face1);
403 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700404 forwarder.addFace(face3);
405 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700406
407 Pit& pit = forwarder.getPit();
408 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
409 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
410 pit0->insertOrUpdateInRecord(face1, *interest0);
411 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
412 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
413 pitA->insertOrUpdateInRecord(face1, *interestA);
414 pitA->insertOrUpdateInRecord(face2, *interestA);
415 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
416 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
417 pitC->insertOrUpdateInRecord(face3, *interestC);
418 pitC->insertOrUpdateInRecord(face4, *interestC);
419
420 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
421 forwarder.onIncomingData(*face3, *dataD);
422 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
423
424 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
425 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
426 BOOST_CHECK_EQUAL(face3->m_sentDatas.size(), 0);
427 BOOST_CHECK_EQUAL(face4->m_sentDatas.size(), 1);
428}
429
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700430BOOST_AUTO_TEST_CASE(IncomingNack)
431{
432 Forwarder forwarder;
433 auto face1 = make_shared<DummyFace>();
434 auto face2 = make_shared<DummyFace>();
435 auto face3 = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>(
436 "dummy://", "dummy://",
437 ndn::nfd::FACE_SCOPE_NON_LOCAL,
438 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
439 ndn::nfd::LINK_TYPE_MULTI_ACCESS));
440 forwarder.addFace(face1);
441 forwarder.addFace(face2);
442 forwarder.addFace(face3);
443
444 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
445 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
446 ref(forwarder), "ndn:/strategyP");
447 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
448 ref(forwarder), "ndn:/strategyQ");
449 strategyChoice.install(strategyP);
450 strategyChoice.install(strategyQ);
451 strategyChoice.insert("ndn:/" , strategyP->getName());
452 strategyChoice.insert("ndn:/B", strategyQ->getName());
453
454 Pit& pit = forwarder.getPit();
455
456 // dispatch to the correct strategy
457 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
458 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
459 pit1->insertOrUpdateOutRecord(face1, *interest1);
460 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
461 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
462 pit2->insertOrUpdateOutRecord(face1, *interest2);
463
464 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
465 strategyP->afterReceiveNack_count = 0;
466 strategyQ->afterReceiveNack_count = 0;
467 forwarder.onIncomingNack(*face1, nack1);
468 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 1);
469 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 0);
470
471 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
472 strategyP->afterReceiveNack_count = 0;
473 strategyQ->afterReceiveNack_count = 0;
474 forwarder.onIncomingNack(*face1, nack2);
475 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 0);
476 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 1);
477
478 // record Nack on PIT out-record
479 pit::OutRecordCollection::const_iterator outRecord1 = pit1->getOutRecord(*face1);
480 BOOST_REQUIRE(outRecord1 != pit1->getOutRecords().end());
481 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
482 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
483
484 // drop if no PIT entry
485 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
486 strategyP->afterReceiveNack_count = 0;
487 strategyQ->afterReceiveNack_count = 0;
488 forwarder.onIncomingNack(*face1, nack3);
489 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 0);
490 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 0);
491
492 // drop if no out-record
493 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
494 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
495 pit4->insertOrUpdateOutRecord(face1, *interest4);
496
497 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
498 strategyP->afterReceiveNack_count = 0;
499 strategyQ->afterReceiveNack_count = 0;
500 forwarder.onIncomingNack(*face2, nack4a);
501 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 0);
502 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 0);
503
504 // drop if Nonce does not match out-record
505 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
506 strategyP->afterReceiveNack_count = 0;
507 strategyQ->afterReceiveNack_count = 0;
508 forwarder.onIncomingNack(*face1, nack4b);
509 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 0);
510 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 0);
511
512 // drop if inFace is multi-access
513 pit4->insertOrUpdateOutRecord(face3, *interest4);
514 strategyP->afterReceiveNack_count = 0;
515 strategyQ->afterReceiveNack_count = 0;
516 forwarder.onIncomingNack(*face3, nack4a);
517 BOOST_CHECK_EQUAL(strategyP->afterReceiveNack_count, 0);
518 BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 0);
519}
520
521BOOST_AUTO_TEST_CASE(OutgoingNack)
522{
523 Forwarder forwarder;
524 auto face1w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>());
525 auto face1 = static_cast<DummyLpFace*>(face1w->getLpFace());
526 auto face2w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>());
527 auto face2 = static_cast<DummyLpFace*>(face2w->getLpFace());
528 auto face3w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>(
529 "dummy://", "dummy://",
530 ndn::nfd::FACE_SCOPE_NON_LOCAL,
531 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
532 ndn::nfd::LINK_TYPE_MULTI_ACCESS));
533 auto face3 = static_cast<DummyLpFace*>(face3w->getLpFace());
534 forwarder.addFace(face1w);
535 forwarder.addFace(face2w);
536 forwarder.addFace(face3w);
537 // TODO#3172 eliminate wrapper
538
539 Pit& pit = forwarder.getPit();
540
541 lp::NackHeader nackHeader;
542 nackHeader.setReason(lp::NackReason::CONGESTION);
543
544 // don't send Nack if there's no in-record
545 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
546 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
547 pit1->insertOrUpdateInRecord(face1w, *interest1);
548
549 face2->sentNacks.clear();
550 forwarder.onOutgoingNack(pit1, *face2w, nackHeader);
551 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
552
553 // send Nack with correct Nonce
554 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
555 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
556 pit2->insertOrUpdateInRecord(face1w, *interest2a);
557 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
558 pit2->insertOrUpdateInRecord(face2w, *interest2b);
559
560 face1->sentNacks.clear();
561 forwarder.onOutgoingNack(pit2, *face1w, nackHeader);
562 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
563 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
564 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
565
566 // erase in-record
567 pit::InRecordCollection::const_iterator inRecord2a = pit2->getInRecord(*face1w);
568 BOOST_CHECK(inRecord2a == pit2->getInRecords().end());
569
570 // send Nack with correct Nonce
571 face2->sentNacks.clear();
572 forwarder.onOutgoingNack(pit2, *face2w, nackHeader);
573 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
574 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
575 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
576
577 // erase in-record
578 pit::InRecordCollection::const_iterator inRecord2b = pit2->getInRecord(*face1w);
579 BOOST_CHECK(inRecord2b == pit2->getInRecords().end());
580
581 // don't send Nack to multi-access face
582 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
583 pit2->insertOrUpdateInRecord(face3w, *interest2c);
584
585 face3->sentNacks.clear();
586 forwarder.onOutgoingNack(pit1, *face3w, nackHeader);
587 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
588}
589
590BOOST_AUTO_TEST_CASE(InterestLoopNack)
591{
592 Forwarder forwarder;
593 auto face1w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>());
594 auto face1 = static_cast<DummyLpFace*>(face1w->getLpFace());
595 auto face2w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>());
596 auto face2 = static_cast<DummyLpFace*>(face2w->getLpFace());
597 auto face3w = make_shared<face::LpFaceWrapper>(make_unique<DummyLpFace>(
598 "dummy://", "dummy://",
599 ndn::nfd::FACE_SCOPE_NON_LOCAL,
600 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
601 ndn::nfd::LINK_TYPE_MULTI_ACCESS));
602 auto face3 = static_cast<DummyLpFace*>(face3w->getLpFace());
603 auto face4 = make_shared<DummyFace>();
604 forwarder.addFace(face1w);
605 forwarder.addFace(face2w);
606 forwarder.addFace(face3w);
607 forwarder.addFace(face4);
608 // TODO#3172 eliminate wrapper
609
610 Fib& fib = forwarder.getFib();
611 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("/zT4XwK0Hnx")).first;
612 fibEntry->addNextHop(face4, 0);
613
614 // receive Interest on face1
615 face1->sentNacks.clear();
616 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
617 face1->receiveInterest(*interest1a);
618 BOOST_CHECK(face1->sentNacks.empty());
619
620 // receive Interest with duplicate Nonce on face1
621 face1->sentNacks.clear();
622 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
623 face1->receiveInterest(*interest1b);
624 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
625 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest(), *interest1b);
626 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
627
628 // receive Interest with duplicate Nonce on face2
629 face2->sentNacks.clear();
630 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
631 face2->receiveInterest(*interest2a);
632 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
633 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
634 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
635
636 // receive Interest with new Nonce on face2
637 face2->sentNacks.clear();
638 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
639 face2->receiveInterest(*interest2b);
640 BOOST_CHECK(face2->sentNacks.empty());
641
642 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
643 face3->sentNacks.clear();
644 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
645 face3->receiveInterest(*interest3a);
646 BOOST_CHECK(face3->sentNacks.empty());
647}
648
Junxiao Shi455581d2014-11-17 18:38:40 -0700649BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700650{
Junxiao Shia110f262014-10-12 12:35:20 -0700651 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700652 auto face1 = make_shared<DummyFace>();
653 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700654 forwarder.addFace(face1);
655 forwarder.addFace(face2);
656
657 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shic099ddb2014-12-25 20:53:20 -0700658 face2->onSendInterest.connect([&face1] (const Interest& interest) {
Junxiao Shi455581d2014-11-17 18:38:40 -0700659 scheduler::schedule(time::milliseconds(170), [&] { face1->receiveInterest(interest); });
Junxiao Shic099ddb2014-12-25 20:53:20 -0700660 });
Junxiao Shia110f262014-10-12 12:35:20 -0700661
662 Fib& fib = forwarder.getFib();
663 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
664 fibEntry->addNextHop(face2, 0);
665
Junxiao Shi455581d2014-11-17 18:38:40 -0700666 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700667 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
668 interest->setNonce(82101183);
669 interest->setInterestLifetime(time::milliseconds(50));
670 face1->receiveInterest(*interest);
671
Junxiao Shi455581d2014-11-17 18:38:40 -0700672 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
673 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
674 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700675
676 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700677
678 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
679 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
680 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
681 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
682 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700683}
684
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700685BOOST_AUTO_TEST_CASE(LinkDelegation)
686{
687 Forwarder forwarder;
688 shared_ptr<Face> face1 = make_shared<DummyFace>();
689 shared_ptr<Face> face2 = make_shared<DummyFace>();
690 forwarder.addFace(face1);
691 forwarder.addFace(face2);
692
693 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
694 auto strategyP = make_shared<DummyStrategy>(ref(forwarder), "ndn:/strategyP");
695 strategyP->wantAfterReceiveInterestCalls = true;
696 strategyChoice.install(strategyP);
697 strategyChoice.insert("ndn:/" , strategyP->getName());
698
699 Fib& fib = forwarder.getFib();
700 Pit& pit = forwarder.getPit();
701 NetworkRegionTable& nrt = forwarder.getNetworkRegionTable();
702
703 // returns prefix of FIB entry during last afterReceiveInterest trigger
704 auto getLastFibPrefix = [strategyP] () -> Name {
705 BOOST_REQUIRE(!strategyP->afterReceiveInterestCalls.empty());
706 return std::get<2>(strategyP->afterReceiveInterestCalls.back())->getPrefix();
707 };
708
709 shared_ptr<Link> link = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
710
711 // consumer region
712 nrt.clear();
713 nrt.insert("/arizona/cs/avenir");
714 shared_ptr<fib::Entry> fibRoot = fib.insert("/").first;
715 fibRoot->addNextHop(face2, 10);
716
717 auto interest1 = makeInterest("/net/ndnsim/www/1.html");
718 interest1->setLink(link->wireEncode());
719 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
720 pit1->insertOrUpdateInRecord(face1, *interest1);
721
722 forwarder.onContentStoreMiss(*face1, pit1, *interest1);
723 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/");
724 BOOST_CHECK_EQUAL(interest1->hasSelectedDelegation(), false);
725
726 fibRoot->removeNextHop(face2);
727
728 // first default-free router, both delegations are available
729 nrt.clear();
730 nrt.insert("/arizona/cs/hobo");
731 shared_ptr<fib::Entry> fibTelia = fib.insert("/telia").first;
732 fibTelia->addNextHop(face2, 10);
733 shared_ptr<fib::Entry> fibUcla = fib.insert("/ucla").first;
734 fibUcla->addNextHop(face2, 10);
735
736 auto interest2 = makeInterest("/net/ndnsim/www/2.html");
737 interest2->setLink(link->wireEncode());
738 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
739 pit2->insertOrUpdateInRecord(face1, *interest2);
740
741 forwarder.onContentStoreMiss(*face1, pit2, *interest2);
742 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/telia");
743 BOOST_REQUIRE_EQUAL(interest2->hasSelectedDelegation(), true);
744 BOOST_CHECK_EQUAL(interest2->getSelectedDelegation(), "/telia/terabits");
745
746 fib.erase(*fibTelia);
747 fib.erase(*fibUcla);
748
749 // first default-free router, only second delegation is available
750 nrt.clear();
751 nrt.insert("/arizona/cs/hobo");
752 fibUcla = fib.insert("/ucla").first;
753 fibUcla->addNextHop(face2, 10);
754
755 auto interest3 = makeInterest("/net/ndnsim/www/3.html");
756 interest3->setLink(link->wireEncode());
757 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
758 pit3->insertOrUpdateInRecord(face1, *interest3);
759
760 forwarder.onContentStoreMiss(*face1, pit3, *interest3);
761 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
762 BOOST_REQUIRE_EQUAL(interest3->hasSelectedDelegation(), true);
763 BOOST_CHECK_EQUAL(interest3->getSelectedDelegation(), "/ucla/cs");
764
765 fib.erase(*fibUcla);
766
767 // default-free router, chosen SelectedDelegation
768 nrt.clear();
769 nrt.insert("/ucsd/caida/click");
770 fibTelia = fib.insert("/telia").first;
771 fibTelia->addNextHop(face2, 10);
772 fibUcla = fib.insert("/ucla").first;
773 fibUcla->addNextHop(face2, 10);
774
775 auto interest4 = makeInterest("/net/ndnsim/www/4.html");
776 interest4->setLink(link->wireEncode());
777 interest4->setSelectedDelegation("/ucla/cs");
778 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
779 pit4->insertOrUpdateInRecord(face1, *interest4);
780
781 forwarder.onContentStoreMiss(*face1, pit4, *interest4);
782 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/ucla");
783 BOOST_REQUIRE_EQUAL(interest4->hasSelectedDelegation(), true);
784 BOOST_CHECK_EQUAL(interest4->getSelectedDelegation(), "/ucla/cs");
785
786 fib.erase(*fibTelia);
787 fib.erase(*fibUcla);
788
789 // producer region
790 nrt.clear();
791 nrt.insert("/ucla/cs/spurs");
792 fibRoot->addNextHop(face2, 10);
793 fibUcla = fib.insert("/ucla").first;
794 fibUcla->addNextHop(face2, 10);
795 shared_ptr<fib::Entry> fibNdnsim = fib.insert("/net/ndnsim").first;
796 fibNdnsim->addNextHop(face2, 10);
797
798 auto interest5 = makeInterest("/net/ndnsim/www/5.html");
799 interest5->setLink(link->wireEncode());
800 interest5->setSelectedDelegation("/ucla/cs");
801 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
802 pit5->insertOrUpdateInRecord(face1, *interest5);
803
804 forwarder.onContentStoreMiss(*face1, pit5, *interest5);
805 BOOST_CHECK_EQUAL(getLastFibPrefix(), "/net/ndnsim");
806 BOOST_REQUIRE_EQUAL(interest5->hasSelectedDelegation(), true);
807 BOOST_CHECK_EQUAL(interest5->getSelectedDelegation(), "/ucla/cs");
808
809 fibRoot->removeNextHop(face2);
810 fib.erase(*fibUcla);
811 fib.erase(*fibNdnsim);
812}
813
814
815class MalformedPacketFixture : public UnitTestTimeFixture
816{
817protected:
818 MalformedPacketFixture()
819 : face1(make_shared<DummyFace>())
820 , face2(make_shared<DummyFace>())
821 {
822 forwarder.addFace(face1);
823 forwarder.addFace(face2);
824 }
825
826 void
827 processInterest(shared_ptr<Interest> badInterest)
828 {
829 forwarder.startProcessInterest(*face1, *badInterest);
830 this->continueProcessPacket();
831 }
832
833 // processData
834
835 // processNack
836
837private:
838 void
839 continueProcessPacket()
840 {
841 this->advanceClocks(time::milliseconds(10), time::seconds(6));
842 }
843
844protected:
845 Forwarder forwarder;
846 shared_ptr<DummyFace> face1; // face of incoming bad packet
847 shared_ptr<DummyFace> face2; // another face for setting up states
848};
849
850BOOST_FIXTURE_TEST_SUITE(MalformedPacket, MalformedPacketFixture)
851
852BOOST_AUTO_TEST_CASE(BadLink)
853{
854 shared_ptr<Interest> goodInterest = makeInterest("ndn:/");
855 Block wire = goodInterest->wireEncode();
856 wire.push_back(ndn::encoding::makeEmptyBlock(tlv::Data)); // bad Link
857 wire.encode();
858
859 auto badInterest = make_shared<Interest>();
860 BOOST_REQUIRE_NO_THROW(badInterest->wireDecode(wire));
861 BOOST_REQUIRE(badInterest->hasLink());
862 BOOST_REQUIRE_THROW(badInterest->getLink(), tlv::Error);
863
864 BOOST_CHECK_NO_THROW(this->processInterest(badInterest));
865}
866
867BOOST_AUTO_TEST_SUITE_END() // MalformedPacket
868
869BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700870BOOST_AUTO_TEST_SUITE_END()
871
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700872} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700873} // namespace nfd