blob: 5ad6efd732a59811f6b46477c59cd970f04e4b4a [file] [log] [blame]
Vince Lehman09131122014-09-09 17:10:11 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Vince Lehmanc2acdcb2015-04-29 11:14:35 -05003 * Copyright (c) 2014-2015, The University of Memphis,
4 * Regents of the University of California,
5 * Arizona Board of Regents.
Vince Lehman09131122014-09-09 17:10:11 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Vince Lehman09131122014-09-09 17:10:11 -050020 **/
21
Vince Lehman02e32992015-03-11 12:31:20 -050022#include "test-common.hpp"
Vince Lehman199e9cf2015-04-07 13:22:16 -050023#include "control-commands.hpp"
Vince Lehman09131122014-09-09 17:10:11 -050024
Vince Lehman02e32992015-03-11 12:31:20 -050025#include "nlsr.hpp"
26
27#include <ndn-cxx/management/nfd-face-event-notification.hpp>
28#include <ndn-cxx/util/dummy-client-face.hpp>
Vince Lehman09131122014-09-09 17:10:11 -050029
30namespace nlsr {
31namespace test {
32
Vince Lehman09131122014-09-09 17:10:11 -050033using ndn::shared_ptr;
34
35BOOST_FIXTURE_TEST_SUITE(TestNlsr, BaseFixture)
36
37BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
38{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060039 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman09131122014-09-09 17:10:11 -050040 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
41
42 // Simulate loading configuration file
43 AdjacencyList& neighbors = nlsr.getAdjacencyList();
44
45 Adjacent neighborA("/ndn/neighborA", "uri://faceA", 25, Adjacent::STATUS_INACTIVE, 0, 0);
46 neighbors.insert(neighborA);
47
48 Adjacent neighborB("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_INACTIVE, 0, 0);
49 neighbors.insert(neighborB);
50
51 Adjacent neighborC("/ndn/neighborC", "uri://faceC", 17, Adjacent::STATUS_INACTIVE, 0, 0);
52 neighbors.insert(neighborC);
53
54 nlsr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
55
56 nlsr.initialize();
57
58 std::list<Adjacent> neighborList = neighbors.getAdjList();
59 for (std::list<Adjacent>::iterator it = neighborList.begin(); it != neighborList.end(); ++it) {
60 BOOST_CHECK_EQUAL(it->getLinkCost(), 0);
61 }
62}
63
64BOOST_AUTO_TEST_CASE(HyperbolicOff_LinkStateCost)
65{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060066 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman09131122014-09-09 17:10:11 -050067 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
68
69 // Simulate loading configuration file
70 AdjacencyList& neighbors = nlsr.getAdjacencyList();
71
72 Adjacent neighborA("/ndn/neighborA", "uri://faceA", 25, Adjacent::STATUS_INACTIVE, 0, 0);
73 neighbors.insert(neighborA);
74
75 Adjacent neighborB("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_INACTIVE, 0, 0);
76 neighbors.insert(neighborB);
77
78 Adjacent neighborC("/ndn/neighborC", "uri://faceC", 17, Adjacent::STATUS_INACTIVE, 0, 0);
79 neighbors.insert(neighborC);
80
81 nlsr.initialize();
82
83 std::list<Adjacent> neighborList = neighbors.getAdjList();
84 for (std::list<Adjacent>::iterator it = neighborList.begin(); it != neighborList.end(); ++it) {
85 BOOST_CHECK(it->getLinkCost() != 0);
86 }
87}
88
Vince Lehman7b616582014-10-17 16:25:39 -050089BOOST_AUTO_TEST_CASE(SetEventIntervals)
90{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060091 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>();
Vince Lehman7b616582014-10-17 16:25:39 -050092 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
93
94 // Simulate loading configuration file
95 ConfParameter& conf = nlsr.getConfParameter();
96 conf.setAdjLsaBuildInterval(3);
97 conf.setFirstHelloInterval(6);
98 conf.setRoutingCalcInterval(9);
99
100 nlsr.initialize();
101
Vince Lehman50df6b72015-03-03 12:06:40 -0600102 const Lsdb& lsdb = nlsr.getLsdb();
Vince Lehman7b616582014-10-17 16:25:39 -0500103 const RoutingTable& rt = nlsr.getRoutingTable();
104
Vince Lehman50df6b72015-03-03 12:06:40 -0600105 BOOST_CHECK_EQUAL(lsdb.getAdjLsaBuildInterval(), ndn::time::seconds(3));
Vince Lehman7b616582014-10-17 16:25:39 -0500106 BOOST_CHECK_EQUAL(nlsr.getFirstHelloInterval(), 6);
107 BOOST_CHECK_EQUAL(rt.getRoutingCalcInterval(), ndn::time::seconds(9));
108}
109
Vince Lehman02e32992015-03-11 12:31:20 -0500110BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, UnitTestTimeFixture)
111{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600112 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehman02e32992015-03-11 12:31:20 -0500113 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
Vince Lehman41b173e2015-05-07 14:13:26 -0500114 Lsdb& lsdb = nlsr.getLsdb();
Vince Lehman02e32992015-03-11 12:31:20 -0500115
116 // Simulate loading configuration file
117 ConfParameter& conf = nlsr.getConfParameter();
118 conf.setNetwork("/ndn");
119 conf.setSiteName("/site");
120 conf.setRouterName("/%C1.router/this-router");
121 conf.setAdjLsaBuildInterval(0);
122 conf.setRoutingCalcInterval(0);
123
124 // Add active neighbors
125 AdjacencyList& neighbors = nlsr.getAdjacencyList();
126
127 uint64_t destroyFaceId = 128;
128
129 // Create a neighbor whose Face will be destroyed
130 Adjacent failNeighbor("/ndn/neighborA", "uri://faceA", 10, Adjacent::STATUS_ACTIVE, 0,
131 destroyFaceId);
132 neighbors.insert(failNeighbor);
133
134 // Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
Vince Lehman41b173e2015-05-07 14:13:26 -0500135 Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman02e32992015-03-11 12:31:20 -0500136 neighbors.insert(otherNeighbor);
137
138 nlsr.initialize();
139
140 // Simulate successful HELLO responses
Vince Lehman41b173e2015-05-07 14:13:26 -0500141 lsdb.scheduleAdjLsaBuild();
142
143 // Set up adjacency LSAs
144 // This router
145 Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 10, Adjacent::STATUS_ACTIVE, 0, 256);
146
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600147 AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10, ndn::time::system_clock::now(), 1, neighbors);
Vince Lehman41b173e2015-05-07 14:13:26 -0500148 lsdb.installAdjLsa(ownAdjLsa);
149
150 // Router that will fail
151 AdjacencyList failAdjacencies;
152 failAdjacencies.insert(thisRouter);
153
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600154 AdjLsa failAdjLsa("/ndn/neighborA", 10,
Vince Lehman41b173e2015-05-07 14:13:26 -0500155 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, failAdjacencies);
156
157 lsdb.installAdjLsa(failAdjLsa);
158
159 // Other router
160 AdjacencyList otherAdjacencies;
161 otherAdjacencies.insert(thisRouter);
162
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600163 AdjLsa otherAdjLsa("/ndn/neighborB", 10,
Vince Lehman41b173e2015-05-07 14:13:26 -0500164 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, otherAdjacencies);
165
166 lsdb.installAdjLsa(otherAdjLsa);
Vince Lehman02e32992015-03-11 12:31:20 -0500167
168 // Run the scheduler to build an adjacency LSA
169 this->advanceClocks(ndn::time::milliseconds(1));
170
171 // Make sure an adjacency LSA was built
172 ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
Vince Lehman41b173e2015-05-07 14:13:26 -0500173 AdjLsa* lsa = lsdb.findAdjLsa(key);
Vince Lehman02e32992015-03-11 12:31:20 -0500174 BOOST_REQUIRE(lsa != nullptr);
175
alvy46ccaae2015-06-25 14:13:39 -0500176 uint32_t lastAdjLsaSeqNo = lsa->getLsSeqNo();
177 nlsr.getSequencingManager().setAdjLsaSeq(lastAdjLsaSeqNo);
Vince Lehman02e32992015-03-11 12:31:20 -0500178
179 // Make sure the routing table was calculated
180 RoutingTableEntry* rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
181 BOOST_REQUIRE(rtEntry != nullptr);
182 BOOST_REQUIRE_EQUAL(rtEntry->getNexthopList().getSize(), 1);
183
184 // Receive FaceEventDestroyed notification
185 ndn::nfd::FaceEventNotification event;
186 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
187 .setFaceId(destroyFaceId);
188
189 shared_ptr<ndn::Data> data = make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
190 data->setContent(event.wireEncode());
191 nlsr.getKeyChain().sign(*data);
192
193 face->receive(*data);
194
195 // Run the scheduler to build an adjacency LSA
196 this->advanceClocks(ndn::time::milliseconds(1));
197
198 Adjacent updatedNeighbor = neighbors.getAdjacent(failNeighbor.getName());
199
200 BOOST_CHECK_EQUAL(updatedNeighbor.getFaceId(), 0);
201 BOOST_CHECK_EQUAL(updatedNeighbor.getInterestTimedOutNo(),
202 nlsr.getConfParameter().getInterestRetryNumber());
203 BOOST_CHECK_EQUAL(updatedNeighbor.getStatus(), Adjacent::STATUS_INACTIVE);
alvy46ccaae2015-06-25 14:13:39 -0500204
205 lsa = lsdb.findAdjLsa(key);
206 BOOST_REQUIRE(lsa != nullptr);
207
208 BOOST_CHECK_EQUAL(lsa->getLsSeqNo(), lastAdjLsaSeqNo + 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500209
210 // Make sure the routing table was recalculated
211 rtEntry = nlsr.getRoutingTable().findRoutingTableEntry(failNeighbor.getName());
212 BOOST_CHECK(rtEntry == nullptr);
213}
214
Vince Lehman199e9cf2015-04-07 13:22:16 -0500215// Bug #2733
216// This test checks that when a face for an inactive node is destroyed, an
217// Adjacency LSA build does not postpone the LSA refresh and cause RIB
218// entries for other nodes' name prefixes to not be refreshed.
219//
220// This test is invalid when Issue #2732 is implemented since an Adjacency LSA
221// refresh will not cause RIB entries for other nodes' name prefixes to be refreshed.
222BOOST_FIXTURE_TEST_CASE(FaceDestroyEventInactive, UnitTestTimeFixture)
223{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600224 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehman199e9cf2015-04-07 13:22:16 -0500225 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
226 Lsdb& lsdb = nlsr.getLsdb();
227
228 // Simulate loading configuration file
229 ConfParameter& conf = nlsr.getConfParameter();
230 conf.setNetwork("/ndn");
231 conf.setSiteName("/site");
232 conf.setRouterName("/%C1.router/this-router");
233 conf.setFirstHelloInterval(0);
234 conf.setAdjLsaBuildInterval(0);
235 conf.setRoutingCalcInterval(0);
236
237 // Add neighbors
238 AdjacencyList& neighbors = nlsr.getAdjacencyList();
239
240 uint64_t destroyFaceId = 128;
241
242 // Create an inactive neighbor whose Face will be destroyed
243 Adjacent failNeighbor("/ndn/neighborA", "uri://faceA", 10, Adjacent::STATUS_INACTIVE, 3,
244 destroyFaceId);
245 neighbors.insert(failNeighbor);
246
247 // Create an additional active neighbor so an adjacency LSA can be built
248 Adjacent otherNeighbor("/ndn/neighborB", "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
249 neighbors.insert(otherNeighbor);
250
251 // Add a name for the neighbor to advertise
252 NamePrefixList nameList;
253 ndn::Name nameToAdvertise("/ndn/neighborB/name");
254 nameList.insert(nameToAdvertise);
255
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600256 NameLsa nameLsa("/ndn/neighborB", 25, ndn::time::system_clock::now(), nameList);
Vince Lehman199e9cf2015-04-07 13:22:16 -0500257 lsdb.installNameLsa(nameLsa);
258
259 nlsr.initialize();
260
261 // Simulate successful HELLO responses from neighbor B
262 lsdb.scheduleAdjLsaBuild();
263
Vince Lehman41b173e2015-05-07 14:13:26 -0500264 // Set up adjacency LSAs
265 // This router
266 Adjacent thisRouter(conf.getRouterPrefix(), "uri://faceB", 25, Adjacent::STATUS_ACTIVE, 0, 256);
267
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600268 AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10, ndn::time::system_clock::now(), 1, neighbors);
Vince Lehman41b173e2015-05-07 14:13:26 -0500269 lsdb.installAdjLsa(ownAdjLsa);
270
271 // Other ACTIVE router
272 AdjacencyList otherAdjacencies;
273 otherAdjacencies.insert(thisRouter);
274
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600275 AdjLsa otherAdjLsa("/ndn/neighborB", 10,
Vince Lehman41b173e2015-05-07 14:13:26 -0500276 ndn::time::system_clock::now() + ndn::time::seconds(3600), 1, otherAdjacencies);
277
278 lsdb.installAdjLsa(otherAdjLsa);
279
Vince Lehman199e9cf2015-04-07 13:22:16 -0500280 // Run the scheduler to build an adjacency LSA
281 this->advanceClocks(ndn::time::milliseconds(1));
282
283 ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
284 AdjLsa* lsa = lsdb.findAdjLsa(key);
285 BOOST_REQUIRE(lsa != nullptr);
286
287 // Cancel previous LSA expiration event
288 g_scheduler.cancelEvent(lsa->getExpiringEventId());
289
290 // Set expiration time for own Adjacency LSA to earlier value for unit-test
291 //
292 // Expiration time is negative to offset the GRACE_PERIOD (10 seconds) automatically applied
293 // to expiration times
294 ndn::EventId id = lsdb.scheduleAdjLsaExpiration(key, lsa->getLsSeqNo(), -ndn::time::seconds(9));
295 lsa->setExpiringEventId(id);
296
297 // Generate a FaceEventDestroyed notification
298 ndn::nfd::FaceEventNotification event;
299 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
300 .setFaceId(destroyFaceId);
301
302 shared_ptr<ndn::Data> data = make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
303 data->setContent(event.wireEncode());
304 nlsr.getKeyChain().sign(*data);
305
306 // Receive the FaceEventDestroyed notification
307 face->receive(*data);
308
309 // Run the scheduler to expire the Adjacency LSA. The expiration should refresh the RIB
310 // entries associated with Neighbor B's advertised prefix.
311 face->sentInterests.clear();
312 this->advanceClocks(ndn::time::seconds(1));
313
314 // The Face should have two sent Interests: the face event and a RIB registration
315 BOOST_REQUIRE(face->sentInterests.size() > 0);
316 const ndn::Interest& interest = face->sentInterests.back();
317
318 ndn::nfd::ControlParameters parameters;
319 ndn::Name::Component verb;
320 BOOST_REQUIRE_NO_THROW(extractRibCommandParameters(interest, verb, parameters));
321
322 BOOST_CHECK_EQUAL(verb, ndn::Name::Component("register"));
323 BOOST_CHECK_EQUAL(parameters.getName(), nameToAdvertise);
324}
325
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500326BOOST_FIXTURE_TEST_CASE(GetCertificate, UnitTestTimeFixture)
327{
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -0600328 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500329 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
330
331 // Create certificate
332 ndn::Name identity("/TestNLSR/identity");
333 identity.appendVersion();
334
335 ndn::KeyChain keyChain;
336 keyChain.createIdentity(identity);
337 ndn::Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
338 shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);
339
340 const ndn::Name certKey = certificate->getName().getPrefix(-1);
341
342 BOOST_CHECK(nlsr.getCertificate(certKey) == nullptr);
343
344 // Certificate should be retrievable from the CertificateStore
345 nlsr.loadCertToPublish(certificate);
346
347 BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
348
349 nlsr.getCertificateStore().clear();
350
351 // Certificate should be retrievable from the cache
352 nlsr.addCertificateToCache(certificate);
353 this->advanceClocks(ndn::time::milliseconds(10));
354
355 BOOST_CHECK(nlsr.getCertificate(certKey) != nullptr);
356}
357
Muktadir R Chowdhury3ac07282016-06-17 16:30:29 -0500358BOOST_FIXTURE_TEST_CASE(SetRouterCommandPrefix, UnitTestTimeFixture)
359{
360 shared_ptr<ndn::util::DummyClientFace> face = make_shared<ndn::util::DummyClientFace>(g_ioService);
361 Nlsr nlsr(g_ioService, g_scheduler, ndn::ref(*face));
362
363 // Simulate loading configuration file
364 ConfParameter& conf = nlsr.getConfParameter();
365 conf.setNetwork("/ndn");
366 conf.setSiteName("/site");
367 conf.setRouterName("/%C1.router/this-router");
368
369 nlsr.initialize();
370
371 BOOST_CHECK_EQUAL(nlsr.getLsdbDatasetHandler().getRouterNameCommandPrefix(),
372 ndn::Name("/ndn/site/%C1.router/this-router/lsdb"));
373}
374
Vince Lehman09131122014-09-09 17:10:11 -0500375BOOST_AUTO_TEST_SUITE_END()
376
377} //namespace test
378} //namespace nlsr