blob: 37cb5f9771e9d67d2939c19af862470c544aac82 [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi330136a2016-03-10 04:53:08 -07003 * Copyright (c) 2014-2016, Regents of the University of California,
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08004 * 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 Shi0e4a1f12016-12-24 02:39:01 +000029#include "choose-strategy.hpp"
Junxiao Shicbc8e942016-09-06 03:17:45 +000030#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi8c8d2182014-01-30 22:33:00 -070031
Junxiao Shid9ee45c2014-02-27 15:38:11 -070032#include "tests/test-common.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070033
34namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070035namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070036
Junxiao Shi0355e9f2015-09-02 07:24:53 -070037BOOST_AUTO_TEST_SUITE(Fw)
Junxiao Shid41d6072016-06-19 23:35:27 +000038BOOST_FIXTURE_TEST_SUITE(TestForwarder, UnitTestTimeFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070039
Junxiao Shi8c8d2182014-01-30 22:33:00 -070040BOOST_AUTO_TEST_CASE(SimpleExchange)
41{
Junxiao Shic041ca32014-02-25 20:01:15 -070042 Forwarder forwarder;
43
Junxiao Shia6de4292016-07-12 02:08:10 +000044 shared_ptr<Interest> interestAB = makeInterest("/A/B");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070045 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000046 shared_ptr<Data> dataABC = makeData("/A/B/C");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070047
Junxiao Shicde37ad2015-12-24 01:02:05 -070048 auto face1 = make_shared<DummyFace>();
49 auto face2 = make_shared<DummyFace>();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070050 forwarder.addFace(face1);
51 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070052
Junxiao Shi8c8d2182014-01-30 22:33:00 -070053 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +000054 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070055
Junxiao Shida93f1f2015-11-11 06:13:16 -070056 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
57 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000058 face1->receiveInterest(*interestAB);
59 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070060 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000061 BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
Junxiao Shicde37ad2015-12-24 01:02:05 -070062 BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
63 BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070064 BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
65 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070066
Junxiao Shida93f1f2015-11-11 06:13:16 -070067 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
68 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
Junxiao Shid41d6072016-06-19 23:35:27 +000069 face2->receiveData(*dataABC);
70 this->advanceClocks(time::milliseconds(100), time::seconds(1));
Junxiao Shicde37ad2015-12-24 01:02:05 -070071 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shia6de4292016-07-12 02:08:10 +000072 BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B/C");
Junxiao Shicde37ad2015-12-24 01:02:05 -070073 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
74 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
Junxiao Shida93f1f2015-11-11 06:13:16 -070075 BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
76 BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070077}
78
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070079BOOST_AUTO_TEST_CASE(CsMatched)
80{
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070081 Forwarder forwarder;
82
Junxiao Shicde37ad2015-12-24 01:02:05 -070083 auto face1 = make_shared<DummyFace>();
84 auto face2 = make_shared<DummyFace>();
85 auto face3 = make_shared<DummyFace>();
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070086 forwarder.addFace(face1);
87 forwarder.addFace(face2);
88 forwarder.addFace(face3);
89
Junxiao Shia6de4292016-07-12 02:08:10 +000090 shared_ptr<Interest> interestA = makeInterest("/A");
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070091 interestA->setInterestLifetime(time::seconds(4));
Junxiao Shia6de4292016-07-12 02:08:10 +000092 shared_ptr<Data> dataA = makeData("/A");
Junxiao Shi0de23a22015-12-03 20:07:02 +000093 dataA->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070094
95 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +000096 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -070097
98 Pit& pit = forwarder.getPit();
99 BOOST_CHECK_EQUAL(pit.size(), 0);
100
101 Cs& cs = forwarder.getCs();
Minsheng Zhangffe8bbb2016-03-10 13:40:37 -0700102 cs.insert(*dataA);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700103
104 face1->receiveInterest(*interestA);
Junxiao Shid41d6072016-06-19 23:35:27 +0000105 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700106 // Interest matching ContentStore should not be forwarded
Junxiao Shicde37ad2015-12-24 01:02:05 -0700107 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700108
Junxiao Shicde37ad2015-12-24 01:02:05 -0700109 BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700110 // IncomingFaceId field should be reset to represent CS
Junxiao Shicde37ad2015-12-24 01:02:05 -0700111 BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
112 BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700113
Junxiao Shid41d6072016-06-19 23:35:27 +0000114 this->advanceClocks(time::milliseconds(100), time::milliseconds(500));
Junxiao Shiad3f1cb2014-08-18 11:12:30 -0700115 // PIT entry should not be left behind
116 BOOST_CHECK_EQUAL(pit.size(), 0);
117}
118
Junxiao Shi891f47b2016-06-20 00:02:11 +0000119BOOST_AUTO_TEST_CASE(OutgoingInterest)
120{
121 Forwarder forwarder;
122 auto face1 = make_shared<DummyFace>();
123 auto face2 = make_shared<DummyFace>();
Junxiao Shi891f47b2016-06-20 00:02:11 +0000124 forwarder.addFace(face1);
125 forwarder.addFace(face2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000126
127 Pit& pit = forwarder.getPit();
Junxiao Shia6de4292016-07-12 02:08:10 +0000128 auto interestA1 = makeInterest("/A");
Junxiao Shi891f47b2016-06-20 00:02:11 +0000129 interestA1->setNonce(8378);
130 shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
Junxiao Shic5f651f2016-11-17 22:58:12 +0000131 pitA->insertOrUpdateInRecord(*face1, *interestA1);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000132
Junxiao Shia6de4292016-07-12 02:08:10 +0000133 auto interestA2 = makeInterest("/A");
Junxiao Shic5f651f2016-11-17 22:58:12 +0000134 interestA2->setNonce(1698);
135 forwarder.onOutgoingInterest(pitA, *face2, *interestA2);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000136
Junxiao Shic5f651f2016-11-17 22:58:12 +0000137 pit::OutRecordCollection::iterator outA2 = pitA->getOutRecord(*face2);
138 BOOST_REQUIRE(outA2 != pitA->out_end());
139 BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000140
Junxiao Shi891f47b2016-06-20 00:02:11 +0000141 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shic5f651f2016-11-17 22:58:12 +0000142 BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
Junxiao Shi891f47b2016-06-20 00:02:11 +0000143}
144
Junxiao Shie342e8d2016-09-18 16:48:00 +0000145BOOST_AUTO_TEST_CASE(NextHopFaceId)
146{
147 Forwarder forwarder;
148
149 auto face1 = make_shared<DummyFace>();
150 auto face2 = make_shared<DummyFace>();
151 auto face3 = make_shared<DummyFace>();
152 forwarder.addFace(face1);
153 forwarder.addFace(face2);
154 forwarder.addFace(face3);
155
156 Fib& fib = forwarder.getFib();
157 fib.insert("/A").first->addNextHop(*face3, 0);
158
159 shared_ptr<Interest> interest = makeInterest("/A/B");
160 interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));
161
162 face1->receiveInterest(*interest);
163 this->advanceClocks(time::milliseconds(100), time::seconds(1));
164 BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
165 BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
166 BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
167}
168
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700169class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -0700170{
171public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700172 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -0700173 {
174 }
175
176 virtual void
Davide Pesaventob84bd3a2016-04-22 02:21:45 +0200177 onDataUnsolicited(Face& inFace, const Data& data) override
Junxiao Shi88884492014-02-15 15:57:43 -0700178 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700179 ++onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700180 }
181
182protected:
183 virtual void
Junxiao Shib9420cf2016-08-13 04:38:52 +0000184 dispatchToStrategy(pit::Entry& pitEntry, function<void(fw::Strategy&)> trigger) override
Junxiao Shi88884492014-02-15 15:57:43 -0700185 {
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700186 ++dispatchToStrategy_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700187 }
188
189public:
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700190 int dispatchToStrategy_count;
191 int onDataUnsolicited_count;
Junxiao Shi88884492014-02-15 15:57:43 -0700192};
193
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700194BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -0700195{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700196 ScopeLocalhostIncomingTestForwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700197 auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
198 auto face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -0700199 forwarder.addFace(face1);
200 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -0700201
Junxiao Shi88884492014-02-15 15:57:43 -0700202 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700203 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700204 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800205 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700206 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700207
Junxiao Shi88884492014-02-15 15:57:43 -0700208 // non-local face, /localhost: violate
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700209 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700210 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800211 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700212 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700213
Junxiao Shi88884492014-02-15 15:57:43 -0700214 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700215 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700216 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800217 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700218 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700219
Junxiao Shi88884492014-02-15 15:57:43 -0700220 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700221 forwarder.dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700222 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800223 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700224 BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700225
Junxiao Shi88884492014-02-15 15:57:43 -0700226 // local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700227 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700228 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800229 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700230 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700231
232 // non-local face, /localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700233 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700234 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800235 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700236 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700237
Junxiao Shi88884492014-02-15 15:57:43 -0700238 // local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700239 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700240 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800241 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700242 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700243
244 // non-local face, non-/localhost: OK
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700245 forwarder.onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700246 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800247 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700248 BOOST_CHECK_EQUAL(forwarder.onDataUnsolicited_count, 1);
Junxiao Shi88884492014-02-15 15:57:43 -0700249}
250
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700251BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
Junxiao Shif3c07812014-03-11 21:48:49 -0700252{
Junxiao Shif3c07812014-03-11 21:48:49 -0700253 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700254 auto face1 = make_shared<DummyFace>();
255 auto face2 = make_shared<DummyFace>();
Junxiao Shif3c07812014-03-11 21:48:49 -0700256 forwarder.addFace(face1);
257 forwarder.addFace(face2);
258
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000259 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
260 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shif3c07812014-03-11 21:48:49 -0700261
262 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000263 strategyA.afterReceiveInterest_count = 0;
264 strategyA.interestOutFace = face2;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700265 forwarder.startProcessInterest(*face1, *interest1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000266 BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700267
268 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000269 strategyB.afterReceiveInterest_count = 0;
270 strategyB.interestOutFace = face2;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700271 forwarder.startProcessInterest(*face1, *interest2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000272 BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700273
Junxiao Shid41d6072016-06-19 23:35:27 +0000274 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shif3c07812014-03-11 21:48:49 -0700275
276 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000277 strategyA.beforeSatisfyInterest_count = 0;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700278 forwarder.startProcessData(*face2, *data1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000279 BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700280
281 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000282 strategyB.beforeSatisfyInterest_count = 0;
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700283 forwarder.startProcessData(*face2, *data2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000284 BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);
Junxiao Shif3c07812014-03-11 21:48:49 -0700285
286 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700287 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700288 forwarder.startProcessInterest(*face1, *interest3);
Junxiao Shif3c07812014-03-11 21:48:49 -0700289 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700290 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700291 forwarder.startProcessInterest(*face1, *interest4);
Junxiao Shif3c07812014-03-11 21:48:49 -0700292
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000293 strategyA.beforeExpirePendingInterest_count = 0;
294 strategyB.beforeExpirePendingInterest_count = 0;
Junxiao Shid41d6072016-06-19 23:35:27 +0000295 this->advanceClocks(time::milliseconds(10), time::milliseconds(100));
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000296 BOOST_CHECK_EQUAL(strategyA.beforeExpirePendingInterest_count, 1);
297 BOOST_CHECK_EQUAL(strategyB.beforeExpirePendingInterest_count, 0);
Junxiao Shif3c07812014-03-11 21:48:49 -0700298}
299
Junxiao Shida006f52014-05-16 11:18:00 -0700300BOOST_AUTO_TEST_CASE(IncomingData)
301{
Junxiao Shida006f52014-05-16 11:18:00 -0700302 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700303 auto face1 = make_shared<DummyFace>();
304 auto face2 = make_shared<DummyFace>();
305 auto face3 = make_shared<DummyFace>();
306 auto face4 = make_shared<DummyFace>();
Junxiao Shida006f52014-05-16 11:18:00 -0700307 forwarder.addFace(face1);
308 forwarder.addFace(face2);
Junxiao Shi223271b2014-07-03 22:06:13 -0700309 forwarder.addFace(face3);
310 forwarder.addFace(face4);
Junxiao Shida006f52014-05-16 11:18:00 -0700311
312 Pit& pit = forwarder.getPit();
313 shared_ptr<Interest> interest0 = makeInterest("ndn:/");
314 shared_ptr<pit::Entry> pit0 = pit.insert(*interest0).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000315 pit0->insertOrUpdateInRecord(*face1, *interest0);
Junxiao Shida006f52014-05-16 11:18:00 -0700316 shared_ptr<Interest> interestA = makeInterest("ndn:/A");
317 shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000318 pitA->insertOrUpdateInRecord(*face1, *interestA);
319 pitA->insertOrUpdateInRecord(*face2, *interestA);
Junxiao Shida006f52014-05-16 11:18:00 -0700320 shared_ptr<Interest> interestC = makeInterest("ndn:/A/B/C");
321 shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000322 pitC->insertOrUpdateInRecord(*face3, *interestC);
323 pitC->insertOrUpdateInRecord(*face4, *interestC);
Junxiao Shida006f52014-05-16 11:18:00 -0700324
325 shared_ptr<Data> dataD = makeData("ndn:/A/B/C/D");
326 forwarder.onIncomingData(*face3, *dataD);
Junxiao Shid41d6072016-06-19 23:35:27 +0000327 this->advanceClocks(time::milliseconds(1), time::milliseconds(5));
Junxiao Shida006f52014-05-16 11:18:00 -0700328
Junxiao Shicde37ad2015-12-24 01:02:05 -0700329 BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
330 BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
331 BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
332 BOOST_CHECK_EQUAL(face4->sentData.size(), 1);
Junxiao Shida006f52014-05-16 11:18:00 -0700333}
334
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700335BOOST_AUTO_TEST_CASE(IncomingNack)
336{
337 Forwarder forwarder;
338 auto face1 = make_shared<DummyFace>();
339 auto face2 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700340 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
341 ndn::nfd::FACE_SCOPE_NON_LOCAL,
342 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
343 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700344 forwarder.addFace(face1);
345 forwarder.addFace(face2);
346 forwarder.addFace(face3);
347
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000348 DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "ndn:/", DummyStrategy::getStrategyName());
349 DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "ndn:/B", DummyStrategy::getStrategyName());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700350
351 Pit& pit = forwarder.getPit();
352
353 // dispatch to the correct strategy
354 shared_ptr<Interest> interest1 = makeInterest("/A/AYJqayrzF", 562);
355 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000356 pit1->insertOrUpdateOutRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700357 shared_ptr<Interest> interest2 = makeInterest("/B/EVyP73ru", 221);
358 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000359 pit2->insertOrUpdateOutRecord(*face1, *interest2);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700360
361 lp::Nack nack1 = makeNack("/A/AYJqayrzF", 562, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000362 strategyA.afterReceiveNack_count = 0;
363 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700364 forwarder.onIncomingNack(*face1, nack1);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000365 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
366 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700367
368 lp::Nack nack2 = makeNack("/B/EVyP73ru", 221, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000369 strategyA.afterReceiveNack_count = 0;
370 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700371 forwarder.onIncomingNack(*face1, nack2);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000372 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
373 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700374
375 // record Nack on PIT out-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700376 pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1);
377 BOOST_REQUIRE(outRecord1 != pit1->out_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700378 BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
379 BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
380
381 // drop if no PIT entry
382 lp::Nack nack3 = makeNack("/yEcw5HhdM", 243, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000383 strategyA.afterReceiveNack_count = 0;
384 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700385 forwarder.onIncomingNack(*face1, nack3);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000386 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
387 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700388
389 // drop if no out-record
390 shared_ptr<Interest> interest4 = makeInterest("/Etab4KpY", 157);
391 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000392 pit4->insertOrUpdateOutRecord(*face1, *interest4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700393
394 lp::Nack nack4a = makeNack("/Etab4KpY", 157, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000395 strategyA.afterReceiveNack_count = 0;
396 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700397 forwarder.onIncomingNack(*face2, nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000398 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
399 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700400
401 // drop if Nonce does not match out-record
402 lp::Nack nack4b = makeNack("/Etab4KpY", 294, lp::NackReason::CONGESTION);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000403 strategyA.afterReceiveNack_count = 0;
404 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700405 forwarder.onIncomingNack(*face1, nack4b);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000406 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
407 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700408
409 // drop if inFace is multi-access
Junxiao Shi9cff7792016-08-01 21:45:11 +0000410 pit4->insertOrUpdateOutRecord(*face3, *interest4);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000411 strategyA.afterReceiveNack_count = 0;
412 strategyB.afterReceiveNack_count = 0;
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700413 forwarder.onIncomingNack(*face3, nack4a);
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000414 BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
415 BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700416}
417
418BOOST_AUTO_TEST_CASE(OutgoingNack)
419{
420 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700421 auto face1 = make_shared<DummyFace>();
422 auto face2 = make_shared<DummyFace>();
423 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
424 ndn::nfd::FACE_SCOPE_NON_LOCAL,
425 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
426 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
427 forwarder.addFace(face1);
428 forwarder.addFace(face2);
429 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700430
431 Pit& pit = forwarder.getPit();
432
433 lp::NackHeader nackHeader;
434 nackHeader.setReason(lp::NackReason::CONGESTION);
435
436 // don't send Nack if there's no in-record
437 shared_ptr<Interest> interest1 = makeInterest("/fM5IVEtC", 719);
438 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000439 pit1->insertOrUpdateInRecord(*face1, *interest1);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700440
441 face2->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700442 forwarder.onOutgoingNack(pit1, *face2, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700443 BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);
444
445 // send Nack with correct Nonce
446 shared_ptr<Interest> interest2a = makeInterest("/Vi8tRm9MG3", 152);
447 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
Junxiao Shi9cff7792016-08-01 21:45:11 +0000448 pit2->insertOrUpdateInRecord(*face1, *interest2a);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700449 shared_ptr<Interest> interest2b = makeInterest("/Vi8tRm9MG3", 808);
Junxiao Shi9cff7792016-08-01 21:45:11 +0000450 pit2->insertOrUpdateInRecord(*face2, *interest2b);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700451
452 face1->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700453 forwarder.onOutgoingNack(pit2, *face1, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700454 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
455 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
456 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
457
458 // erase in-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700459 pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1);
460 BOOST_CHECK(inRecord2a == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700461
462 // send Nack with correct Nonce
463 face2->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700464 forwarder.onOutgoingNack(pit2, *face2, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700465 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
466 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
467 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
468
469 // erase in-record
Junxiao Shi4846f372016-04-05 13:39:30 -0700470 pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1);
471 BOOST_CHECK(inRecord2b == pit2->in_end());
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700472
473 // don't send Nack to multi-access face
474 shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
Junxiao Shi9cff7792016-08-01 21:45:11 +0000475 pit2->insertOrUpdateInRecord(*face3, *interest2c);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700476
477 face3->sentNacks.clear();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700478 forwarder.onOutgoingNack(pit1, *face3, nackHeader);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700479 BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
480}
481
482BOOST_AUTO_TEST_CASE(InterestLoopNack)
483{
484 Forwarder forwarder;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700485 auto face1 = make_shared<DummyFace>();
486 auto face2 = make_shared<DummyFace>();
487 auto face3 = make_shared<DummyFace>("dummy://", "dummy://",
488 ndn::nfd::FACE_SCOPE_NON_LOCAL,
489 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
490 ndn::nfd::LINK_TYPE_MULTI_ACCESS);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700491 auto face4 = make_shared<DummyFace>();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700492 forwarder.addFace(face1);
493 forwarder.addFace(face2);
494 forwarder.addFace(face3);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700495 forwarder.addFace(face4);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700496
497 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000498 fib.insert("/zT4XwK0Hnx").first->addNextHop(*face4, 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700499
500 // receive Interest on face1
501 face1->sentNacks.clear();
502 shared_ptr<Interest> interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
503 face1->receiveInterest(*interest1a);
504 BOOST_CHECK(face1->sentNacks.empty());
505
506 // receive Interest with duplicate Nonce on face1
507 face1->sentNacks.clear();
508 shared_ptr<Interest> interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
509 face1->receiveInterest(*interest1b);
510 BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
511 BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest(), *interest1b);
512 BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
513
514 // receive Interest with duplicate Nonce on face2
515 face2->sentNacks.clear();
516 shared_ptr<Interest> interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
517 face2->receiveInterest(*interest2a);
518 BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
519 BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest(), *interest2a);
520 BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);
521
522 // receive Interest with new Nonce on face2
523 face2->sentNacks.clear();
524 shared_ptr<Interest> interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 944);
525 face2->receiveInterest(*interest2b);
526 BOOST_CHECK(face2->sentNacks.empty());
527
528 // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
529 face3->sentNacks.clear();
530 shared_ptr<Interest> interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", 732);
531 face3->receiveInterest(*interest3a);
532 BOOST_CHECK(face3->sentNacks.empty());
533}
534
Junxiao Shi455581d2014-11-17 18:38:40 -0700535BOOST_FIXTURE_TEST_CASE(InterestLoopWithShortLifetime, UnitTestTimeFixture) // Bug 1953
Junxiao Shia110f262014-10-12 12:35:20 -0700536{
Junxiao Shia110f262014-10-12 12:35:20 -0700537 Forwarder forwarder;
Junxiao Shi455581d2014-11-17 18:38:40 -0700538 auto face1 = make_shared<DummyFace>();
539 auto face2 = make_shared<DummyFace>();
Junxiao Shia110f262014-10-12 12:35:20 -0700540 forwarder.addFace(face1);
541 forwarder.addFace(face2);
542
543 // cause an Interest sent out of face2 to loop back into face1 after a delay
Junxiao Shicde37ad2015-12-24 01:02:05 -0700544 face2->afterSend.connect([face1, face2] (uint32_t pktType) {
545 if (pktType == tlv::Interest) {
546 auto interest = make_shared<Interest>(face2->sentInterests.back());
547 scheduler::schedule(time::milliseconds(170), [face1, interest] { face1->receiveInterest(*interest); });
548 }
Junxiao Shic099ddb2014-12-25 20:53:20 -0700549 });
Junxiao Shia110f262014-10-12 12:35:20 -0700550
551 Fib& fib = forwarder.getFib();
Junxiao Shia6de4292016-07-12 02:08:10 +0000552 fib.insert("/A").first->addNextHop(*face2, 0);
Junxiao Shia110f262014-10-12 12:35:20 -0700553
Junxiao Shi455581d2014-11-17 18:38:40 -0700554 // receive an Interest
Junxiao Shia110f262014-10-12 12:35:20 -0700555 shared_ptr<Interest> interest = makeInterest("ndn:/A/1");
556 interest->setNonce(82101183);
557 interest->setInterestLifetime(time::milliseconds(50));
558 face1->receiveInterest(*interest);
559
Junxiao Shi455581d2014-11-17 18:38:40 -0700560 // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
561 BOOST_ASSERT(time::milliseconds(25) * 40 < forwarder.getDeadNonceList().getLifetime());
562 this->advanceClocks(time::milliseconds(25), 40);
Junxiao Shia110f262014-10-12 12:35:20 -0700563
Junxiao Shicde37ad2015-12-24 01:02:05 -0700564 BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);
Junxiao Shi455581d2014-11-17 18:38:40 -0700565
566 // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
567 // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
568 // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
569 // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
570 // an Interest if its Name+Nonce has appeared any point in the past.
Junxiao Shia110f262014-10-12 12:35:20 -0700571}
572
Junxiao Shid41d6072016-06-19 23:35:27 +0000573BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
Junxiao Shi330136a2016-03-10 04:53:08 -0700574{
575 Forwarder forwarder;
576 shared_ptr<Face> face1 = make_shared<DummyFace>();
577 forwarder.addFace(face1);
578
579 shared_ptr<Interest> interest = makeInterest("ndn:/hcLSAsQ9A");
580 interest->setNonce(61883075);
581 interest->setInterestLifetime(time::seconds(2));
582
583 DeadNonceList& dnl = forwarder.getDeadNonceList();
584 dnl.add(interest->getName(), interest->getNonce());
585 Pit& pit = forwarder.getPit();
586 BOOST_REQUIRE_EQUAL(pit.size(), 0);
587
588 forwarder.startProcessInterest(*face1, *interest);
589 this->advanceClocks(time::milliseconds(100), time::seconds(20));
590 BOOST_CHECK_EQUAL(pit.size(), 0);
591}
592
Junxiao Shi0355e9f2015-09-02 07:24:53 -0700593
594class MalformedPacketFixture : public UnitTestTimeFixture
595{
596protected:
597 MalformedPacketFixture()
598 : face1(make_shared<DummyFace>())
599 , face2(make_shared<DummyFace>())
600 {
601 forwarder.addFace(face1);
602 forwarder.addFace(face2);
603 }
604
605 void
606 processInterest(shared_ptr<Interest> badInterest)
607 {
608 forwarder.startProcessInterest(*face1, *badInterest);
609 this->continueProcessPacket();
610 }
611
612 // processData
613
614 // processNack
615
616private:
617 void
618 continueProcessPacket()
619 {
620 this->advanceClocks(time::milliseconds(10), time::seconds(6));
621 }
622
623protected:
624 Forwarder forwarder;
625 shared_ptr<DummyFace> face1; // face of incoming bad packet
626 shared_ptr<DummyFace> face2; // another face for setting up states
627};
628
629BOOST_FIXTURE_TEST_SUITE(MalformedPacket, MalformedPacketFixture)
630
631BOOST_AUTO_TEST_CASE(BadLink)
632{
633 shared_ptr<Interest> goodInterest = makeInterest("ndn:/");
634 Block wire = goodInterest->wireEncode();
635 wire.push_back(ndn::encoding::makeEmptyBlock(tlv::Data)); // bad Link
636 wire.encode();
637
638 auto badInterest = make_shared<Interest>();
639 BOOST_REQUIRE_NO_THROW(badInterest->wireDecode(wire));
640 BOOST_REQUIRE(badInterest->hasLink());
641 BOOST_REQUIRE_THROW(badInterest->getLink(), tlv::Error);
642
643 BOOST_CHECK_NO_THROW(this->processInterest(badInterest));
644}
645
646BOOST_AUTO_TEST_SUITE_END() // MalformedPacket
647
648BOOST_AUTO_TEST_SUITE_END()
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700649BOOST_AUTO_TEST_SUITE_END()
650
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700651} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700652} // namespace nfd