blob: 6c4620598f392195cbfa8f2a20d6e66432ca326c [file] [log] [blame]
Vince Lehman09131122014-09-09 17:10:11 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi0b1b7d92019-05-22 15:37:18 +00002/*
Saurab Dulal427e0122019-11-28 11:58:02 -06003 * Copyright (c) 2014-2020, The University of Memphis,
Vince Lehmanc2acdcb2015-04-29 11:14:35 -05004 * 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/>.
Junxiao Shi0b1b7d92019-05-22 15:37:18 +000020 */
Vince Lehman09131122014-09-09 17:10:11 -050021
Ashlesh Gawande3909aa12017-07-28 16:01:35 -050022#include "nlsr.hpp"
Vince Lehman02e32992015-03-11 12:31:20 -050023#include "test-common.hpp"
Vince Lehman199e9cf2015-04-07 13:22:16 -050024#include "control-commands.hpp"
Nick Gordonc0c6bcf2017-08-15 18:11:21 -050025#include "logger.hpp"
Vince Lehman09131122014-09-09 17:10:11 -050026
Junxiao Shi3e5120c2016-09-10 16:58:34 +000027#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
Vince Lehman09131122014-09-09 17:10:11 -050028
29namespace nlsr {
30namespace test {
31
Ashlesh Gawande85998a12017-12-07 22:22:13 -060032using namespace ndn::time_literals;
Vince Lehman09131122014-09-09 17:10:11 -050033
Nick Gordond5c1a372016-10-31 13:56:23 -050034class NlsrFixture : public MockNfdMgmtFixture
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050035{
36public:
37 NlsrFixture()
Saurab Dulal427e0122019-11-28 11:58:02 -060038 : conf(m_face, m_keyChain)
Ashlesh Gawande85998a12017-12-07 22:22:13 -060039 , confProcessor(conf)
40 , nlsr(m_face, m_keyChain, conf)
41 , lsdb(nlsr.m_lsdb)
42 , neighbors(conf.getAdjacencyList())
Nick Gordond5c1a372016-10-31 13:56:23 -050043 , nSuccessCallbacks(0)
44 , nFailureCallbacks(0)
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050045 {
Ashlesh Gawande85998a12017-12-07 22:22:13 -060046 addIdentity(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050047 }
48
49 void
50 receiveHelloData(const ndn::Name& sender, const ndn::Name& receiver)
51 {
52 ndn::Name dataName(sender);
53 dataName.append("NLSR").append("INFO").append(receiver.wireEncode()).appendVersion();
54
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050055 ndn::Data data(dataName);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050056
57 nlsr.m_helloProtocol.onContentValidated(data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050058 }
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050059
60public:
Ashlesh Gawande85998a12017-12-07 22:22:13 -060061 ConfParameter conf;
62 DummyConfFileProcessor confProcessor;
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050063 Nlsr nlsr;
64 Lsdb& lsdb;
65 AdjacencyList& neighbors;
Nick Gordond5c1a372016-10-31 13:56:23 -050066 uint32_t nSuccessCallbacks;
67 uint32_t nFailureCallbacks;
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050068 ndn::util::signal::ScopedConnection connection;
Vince Lehmanf7eec4f2015-05-08 19:02:31 -050069};
70
71BOOST_FIXTURE_TEST_SUITE(TestNlsr, NlsrFixture)
Vince Lehman09131122014-09-09 17:10:11 -050072
73BOOST_AUTO_TEST_CASE(HyperbolicOn_ZeroCostNeighbors)
74{
Vince Lehman09131122014-09-09 17:10:11 -050075 // Simulate loading configuration file
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050076 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Nick Gordon727d4832017-10-13 18:04:25 -050077 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050078 neighbors.insert(neighborA);
79
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050080 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Nick Gordon727d4832017-10-13 18:04:25 -050081 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050082 neighbors.insert(neighborB);
83
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050084 Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Nick Gordon727d4832017-10-13 18:04:25 -050085 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -050086 neighbors.insert(neighborC);
87
Ashlesh Gawande85998a12017-12-07 22:22:13 -060088 conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
Vince Lehman09131122014-09-09 17:10:11 -050089
90 nlsr.initialize();
91
Davide Pesaventod8d6bbc2020-11-24 21:38:44 -050092 for (const auto& neighbor : neighbors.getAdjList()) {
Ashlesh Gawande57a87172020-05-09 19:47:06 -070093 BOOST_CHECK_EQUAL(neighbor.getLinkCost(), 0);
Vince Lehman09131122014-09-09 17:10:11 -050094 }
95}
96
97BOOST_AUTO_TEST_CASE(HyperbolicOff_LinkStateCost)
98{
Vince Lehman09131122014-09-09 17:10:11 -050099 // Simulate loading configuration file
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500100 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"), 25,
Nick Gordon727d4832017-10-13 18:04:25 -0500101 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500102 neighbors.insert(neighborA);
103
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500104 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500105 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500106 neighbors.insert(neighborB);
107
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500108 Adjacent neighborC("/ndn/neighborC", ndn::FaceUri("udp4://10.0.0.3"), 17,
Nick Gordon727d4832017-10-13 18:04:25 -0500109 Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehman09131122014-09-09 17:10:11 -0500110 neighbors.insert(neighborC);
111
112 nlsr.initialize();
113
Davide Pesaventod8d6bbc2020-11-24 21:38:44 -0500114 for (const auto& neighbor : neighbors.getAdjList()) {
115 BOOST_CHECK_NE(neighbor.getLinkCost(), 0);
Vince Lehman09131122014-09-09 17:10:11 -0500116 }
117}
118
Vince Lehman7b616582014-10-17 16:25:39 -0500119BOOST_AUTO_TEST_CASE(SetEventIntervals)
120{
Vince Lehman7b616582014-10-17 16:25:39 -0500121 // Simulate loading configuration file
Vince Lehman7b616582014-10-17 16:25:39 -0500122 conf.setAdjLsaBuildInterval(3);
Vince Lehman7b616582014-10-17 16:25:39 -0500123 conf.setRoutingCalcInterval(9);
124
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600125 Nlsr nlsr2(m_face, m_keyChain, conf);
Vince Lehman7b616582014-10-17 16:25:39 -0500126
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600127 const Lsdb& lsdb = nlsr2.m_lsdb;
128 const RoutingTable& rt = nlsr2.m_routingTable;
Vince Lehman7b616582014-10-17 16:25:39 -0500129
Ashlesh Gawande15052402018-12-12 20:20:00 -0600130 BOOST_CHECK_EQUAL(lsdb.m_adjLsaBuildInterval, ndn::time::seconds(3));
Vince Lehman7b616582014-10-17 16:25:39 -0500131 BOOST_CHECK_EQUAL(rt.getRoutingCalcInterval(), ndn::time::seconds(9));
132}
133
Nick Gordond5c1a372016-10-31 13:56:23 -0500134BOOST_AUTO_TEST_CASE(FaceCreateEvent)
135{
136 // Setting constants for the unit test
137 const uint32_t faceId = 1;
138 const std::string faceUri = "udp4://10.0.0.1:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500139
140 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500141 Adjacent::STATUS_INACTIVE, 0, 0);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500142
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800143 BOOST_REQUIRE_EQUAL(conf.getAdjacencyList().insert(neighbor), true);
Nick Gordond5c1a372016-10-31 13:56:23 -0500144
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600145 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500146
147 // Build, sign, and send the Face Event
148 ndn::nfd::FaceEventNotification event;
149 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
150 .setRemoteUri(faceUri)
151 .setFaceId(faceId);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600152 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000153 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500154 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600155 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500156 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500157
158 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600159 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500160
161 // Need to explicitly provide a FaceUri object, because the
162 // conversion will attempt to create Name objects.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600163 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
164 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500165 BOOST_CHECK_EQUAL(iterator->getFaceId(), faceId);
166}
167
168BOOST_AUTO_TEST_CASE(FaceCreateEventNoMatch)
169{
170 // Setting constants for the unit test
171 const uint32_t faceId = 1;
172 const std::string eventUri = "udp4://10.0.0.1:6363";
173 const std::string neighborUri = "udp4://10.0.0.2:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500174
175 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(neighborUri), 10,
Nick Gordon727d4832017-10-13 18:04:25 -0500176 Adjacent::STATUS_INACTIVE, 0, 0);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500177
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600178 conf.getAdjacencyList().insert(neighbor);
Nick Gordond5c1a372016-10-31 13:56:23 -0500179
180 // Build, sign, and send the Face Event
181 ndn::nfd::FaceEventNotification event;
182 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
183 .setRemoteUri(eventUri)
184 .setFaceId(faceId);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600185 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000186 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500187 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600188 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500189 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500190
191 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600192 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500193
194 // The Face URIs did not match, so this neighbor should be unconfigured.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600195 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(neighborUri));
196 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500197 BOOST_CHECK_EQUAL(iterator->getFaceId(), 0);
198}
199
200BOOST_AUTO_TEST_CASE(FaceCreateEventAlreadyConfigured)
201{
Ashlesh Gawande41878572019-09-29 00:16:02 -0500202 // So if NLSR gets the notification and registers prefixes it
203 // will change the Id to 1 and our tests will fail
204 // Need to disable registrationReply in dummy face and have own registration reply in the future
205 const uint32_t neighborFaceId = 1;
Nick Gordond5c1a372016-10-31 13:56:23 -0500206 const std::string faceUri = "udp4://10.0.0.1:6363";
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500207
208 Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
Ashlesh Gawande41878572019-09-29 00:16:02 -0500209 Adjacent::STATUS_ACTIVE, 0, 0);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600210 conf.getAdjacencyList().insert(neighbor);
Nick Gordond5c1a372016-10-31 13:56:23 -0500211
Ashlesh Gawande41878572019-09-29 00:16:02 -0500212 // Let NLSR start the face monitor
213 this->advanceClocks(10_ms);
214
Nick Gordond5c1a372016-10-31 13:56:23 -0500215 // Build, sign, and send the Face Event
216 ndn::nfd::FaceEventNotification event;
217 event.setKind(ndn::nfd::FACE_EVENT_CREATED)
218 .setRemoteUri(faceUri)
Ashlesh Gawande41878572019-09-29 00:16:02 -0500219 .setFaceId(neighborFaceId); // Does not matter what we set here, dummy face always returns 1
Nick Gordond5c1a372016-10-31 13:56:23 -0500220 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000221 data->setFreshnessPeriod(1_s);
Nick Gordond5c1a372016-10-31 13:56:23 -0500222 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600223 m_keyChain.sign(*data);
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500224 m_face.receive(*data);
Nick Gordond5c1a372016-10-31 13:56:23 -0500225
226 // Move the clocks forward so that the Face processes the event.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600227 this->advanceClocks(10_ms);
Nick Gordond5c1a372016-10-31 13:56:23 -0500228
Ashlesh Gawande41878572019-09-29 00:16:02 -0500229 // Check that the neighbor is configured with the face id of 1
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600230 auto iterator = conf.getAdjacencyList().findAdjacent(ndn::FaceUri(faceUri));
231 BOOST_REQUIRE(iterator != conf.getAdjacencyList().end());
Nick Gordond5c1a372016-10-31 13:56:23 -0500232 BOOST_CHECK_EQUAL(iterator->getFaceId(), neighborFaceId);
Ashlesh Gawande41878572019-09-29 00:16:02 -0500233
234 // Resend same event notification again
235 m_face.sentInterests.clear();
236 data->setName("/localhost/nfd/faces/events/%FE%01");
237 m_keyChain.sign(*data);
238 m_face.receive(*data);
239 this->advanceClocks(10_ms);
240
241 for (const auto& interest : m_face.sentInterests) {
242 // Should not re-register prefix since this is the same event notification
243 if (ndn::Name("/localhost/nfd/rib/register").isPrefixOf(interest.getName())) {
244 BOOST_CHECK(false);
245 }
246 }
Nick Gordond5c1a372016-10-31 13:56:23 -0500247}
248
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500249BOOST_AUTO_TEST_CASE(FaceDestroyEvent)
Vince Lehman02e32992015-03-11 12:31:20 -0500250{
Vince Lehman02e32992015-03-11 12:31:20 -0500251 // Add active neighbors
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600252 AdjacencyList& neighbors = conf.getAdjacencyList();
Vince Lehman02e32992015-03-11 12:31:20 -0500253 uint64_t destroyFaceId = 128;
254
255 // Create a neighbor whose Face will be destroyed
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500256 Adjacent failNeighbor("/ndn/neighborA", ndn::FaceUri("udp4://10.0.0.1"),
257 10, Adjacent::STATUS_ACTIVE, 0, destroyFaceId);
Vince Lehman02e32992015-03-11 12:31:20 -0500258 neighbors.insert(failNeighbor);
259
260 // Create an additional neighbor so an adjacency LSA can be built after the face is destroyed
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500261 Adjacent otherNeighbor("/ndn/neighborB", ndn::FaceUri("udp4://10.0.0.2"),
262 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman02e32992015-03-11 12:31:20 -0500263 neighbors.insert(otherNeighbor);
264
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -0500265 // Set HelloInterest lifetime as 10 seconds so that neighbors are not marked INACTIVE
266 // upon timeout before this test ends
267 conf.setInterestResendTime(10);
Vince Lehman02e32992015-03-11 12:31:20 -0500268 nlsr.initialize();
269
270 // Simulate successful HELLO responses
Vince Lehman41b173e2015-05-07 14:13:26 -0500271 lsdb.scheduleAdjLsaBuild();
272
273 // Set up adjacency LSAs
274 // This router
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500275 Adjacent thisRouter(conf.getRouterPrefix(), ndn::FaceUri("udp4://10.0.0.3"),
276 10, Adjacent::STATUS_ACTIVE, 0, 256);
Vince Lehman41b173e2015-05-07 14:13:26 -0500277
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500278 AdjLsa ownAdjLsa(conf.getRouterPrefix(), 10,
279 ndn::time::system_clock::now(), 1, neighbors);
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700280 lsdb.installLsa(std::make_shared<AdjLsa>(ownAdjLsa));
Vince Lehman41b173e2015-05-07 14:13:26 -0500281
282 // Router that will fail
283 AdjacencyList failAdjacencies;
284 failAdjacencies.insert(thisRouter);
285
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600286 AdjLsa failAdjLsa("/ndn/neighborA", 10,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500287 ndn::time::system_clock::now() + ndn::time::seconds(3600),
288 1, failAdjacencies);
Vince Lehman41b173e2015-05-07 14:13:26 -0500289
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700290 lsdb.installLsa(std::make_shared<AdjLsa>(failAdjLsa));
Vince Lehman41b173e2015-05-07 14:13:26 -0500291
292 // Other router
293 AdjacencyList otherAdjacencies;
294 otherAdjacencies.insert(thisRouter);
295
Ashlesh Gawanded02c3882015-12-29 16:02:51 -0600296 AdjLsa otherAdjLsa("/ndn/neighborB", 10,
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500297 ndn::time::system_clock::now() + ndn::time::seconds(3600),
298 1, otherAdjacencies);
Vince Lehman41b173e2015-05-07 14:13:26 -0500299
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700300 lsdb.installLsa(std::make_shared<AdjLsa>(otherAdjLsa));
Vince Lehman02e32992015-03-11 12:31:20 -0500301
302 // Run the scheduler to build an adjacency LSA
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600303 this->advanceClocks(10_ms);
Vince Lehman02e32992015-03-11 12:31:20 -0500304
305 // Make sure an adjacency LSA was built
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700306 auto lsa = lsdb.findLsa(conf.getRouterPrefix(), Lsa::Type::ADJACENCY);
Vince Lehman02e32992015-03-11 12:31:20 -0500307 BOOST_REQUIRE(lsa != nullptr);
308
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800309 uint32_t lastAdjLsaSeqNo = lsa->getSeqNo();
Ashlesh Gawande15052402018-12-12 20:20:00 -0600310 nlsr.m_lsdb.m_sequencingManager.setAdjLsaSeq(lastAdjLsaSeqNo);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600311
312 this->advanceClocks(1500_ms, 10);
Vince Lehman02e32992015-03-11 12:31:20 -0500313
314 // Make sure the routing table was calculated
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600315 RoutingTableEntry* rtEntry = nlsr.m_routingTable.findRoutingTableEntry(failNeighbor.getName());
Vince Lehman02e32992015-03-11 12:31:20 -0500316 BOOST_REQUIRE(rtEntry != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500317 BOOST_REQUIRE_EQUAL(rtEntry->getNexthopList().size(), 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500318
319 // Receive FaceEventDestroyed notification
320 ndn::nfd::FaceEventNotification event;
321 event.setKind(ndn::nfd::FACE_EVENT_DESTROYED)
322 .setFaceId(destroyFaceId);
323
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700324 auto data = std::make_shared<ndn::Data>("/localhost/nfd/faces/events/%FE%00");
Junxiao Shi0b1b7d92019-05-22 15:37:18 +0000325 data->setFreshnessPeriod(1_s);
Vince Lehman02e32992015-03-11 12:31:20 -0500326 data->setContent(event.wireEncode());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600327 m_keyChain.sign(*data);
Vince Lehman02e32992015-03-11 12:31:20 -0500328
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500329 m_face.receive(*data);
Vince Lehman02e32992015-03-11 12:31:20 -0500330
331 // Run the scheduler to build an adjacency LSA
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600332 this->advanceClocks(10_ms);
Vince Lehman02e32992015-03-11 12:31:20 -0500333
334 Adjacent updatedNeighbor = neighbors.getAdjacent(failNeighbor.getName());
335
336 BOOST_CHECK_EQUAL(updatedNeighbor.getFaceId(), 0);
337 BOOST_CHECK_EQUAL(updatedNeighbor.getInterestTimedOutNo(),
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600338 conf.getInterestRetryNumber());
Vince Lehman02e32992015-03-11 12:31:20 -0500339 BOOST_CHECK_EQUAL(updatedNeighbor.getStatus(), Adjacent::STATUS_INACTIVE);
alvy46ccaae2015-06-25 14:13:39 -0500340
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700341 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
alvy46ccaae2015-06-25 14:13:39 -0500342 BOOST_REQUIRE(lsa != nullptr);
343
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800344 BOOST_CHECK_EQUAL(lsa->getSeqNo(), lastAdjLsaSeqNo + 1);
Vince Lehman02e32992015-03-11 12:31:20 -0500345
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600346 this->advanceClocks(15_s, 10);
347
Vince Lehman02e32992015-03-11 12:31:20 -0500348 // Make sure the routing table was recalculated
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600349 rtEntry = nlsr.m_routingTable.findRoutingTableEntry(failNeighbor.getName());
Vince Lehman02e32992015-03-11 12:31:20 -0500350 BOOST_CHECK(rtEntry == nullptr);
351}
352
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500353BOOST_AUTO_TEST_CASE(BuildAdjLsaAfterHelloResponse)
354{
355 // Configure NLSR
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500356 conf.setAdjLsaBuildInterval(1);
357
358 // Add neighbors
359 // Router A
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500360 ndn::Name neighborAName("/ndn/site/%C1.Router/routerA");
361 Adjacent neighborA(neighborAName, ndn::FaceUri("udp4://10.0.0.1"),
362 0, Adjacent::STATUS_INACTIVE, 0, 0);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500363 neighbors.insert(neighborA);
364
365 // Router B
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500366 ndn::Name neighborBName("/ndn/site/%C1.Router/routerB");
367 Adjacent neighborB(neighborBName, ndn::FaceUri("udp4://10.0.0.1"),
368 0, Adjacent::STATUS_INACTIVE, 0, 0);
369
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500370 neighbors.insert(neighborB);
371
372 nlsr.initialize();
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500373
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600374 this->advanceClocks(10_ms);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500375
376 // Receive HELLO response from Router A
377 receiveHelloData(neighborAName, conf.getRouterPrefix());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600378 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500379
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500380 // Adjacency LSA should be built even though other router is INACTIVE
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700381 auto lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500382 BOOST_REQUIRE(lsa != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500383 BOOST_CHECK_EQUAL(lsa->getAdl().size(), 1);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500384
385 // Receive HELLO response from Router B
386 receiveHelloData(neighborBName, conf.getRouterPrefix());
387
388 // Both routers become INACTIVE and HELLO Interests have timed out
389 for (Adjacent& adjacency : neighbors.getAdjList()) {
390 adjacency.setStatus(Adjacent::STATUS_INACTIVE);
391 adjacency.setInterestTimedOutNo(HELLO_RETRIES_DEFAULT);
392 }
393
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600394 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500395
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500396 // Adjacency LSA should have been removed since this router's adjacencies are
397 // INACTIVE and have timed out
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700398 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500399 BOOST_CHECK(lsa == nullptr);
400
401 // Receive HELLO response from Router A and B
402 receiveHelloData(neighborAName, conf.getRouterPrefix());
403 receiveHelloData(neighborBName, conf.getRouterPrefix());
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600404 this->advanceClocks(1_s, 10);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500405
406 // Adjacency LSA should be built
Ashlesh Gawande57a87172020-05-09 19:47:06 -0700407 lsa = lsdb.findLsa<AdjLsa>(conf.getRouterPrefix());
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500408 BOOST_REQUIRE(lsa != nullptr);
Nick Gordonff9a6272017-10-12 13:38:29 -0500409 BOOST_CHECK_EQUAL(lsa->getAdl().size(), 2);
Vince Lehmanf7eec4f2015-05-08 19:02:31 -0500410}
411
Nick Gordond5c1a372016-10-31 13:56:23 -0500412BOOST_AUTO_TEST_CASE(FaceDatasetFetchSuccess)
413{
414 bool hasResult = false;
Nick Gordond5c1a372016-10-31 13:56:23 -0500415
416 nlsr.initializeFaces([&hasResult] (const std::vector<ndn::nfd::FaceStatus>& faces) {
417 hasResult = true;
418 BOOST_CHECK_EQUAL(faces.size(), 2);
419 BOOST_CHECK_EQUAL(faces.front().getFaceId(), 25401);
420 BOOST_CHECK_EQUAL(faces.back().getFaceId(), 25402);
421 },
422 [] (uint32_t code, const std::string& reason) {});
423
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600424 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500425
426 ndn::nfd::FaceStatus payload1;
427 payload1.setFaceId(25401);
428 ndn::nfd::FaceStatus payload2;
429 payload2.setFaceId(25402);
430 this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
431
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600432 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500433 BOOST_CHECK(hasResult);
434}
435
436BOOST_AUTO_TEST_CASE(FaceDatasetFetchFailure)
437{
Nick Gordond5c1a372016-10-31 13:56:23 -0500438 nlsr.initializeFaces([](const std::vector<ndn::nfd::FaceStatus>& faces) {},
439 [this](uint32_t code, const std::string& reason){
440 this->nFailureCallbacks++;
441 });
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600442 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500443
444 ndn::Name payload;
445 this->sendDataset("/localhost/nfd/faces/list", payload);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600446 this->advanceClocks(100_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500447
448 BOOST_CHECK_EQUAL(nFailureCallbacks, 1);
449 BOOST_CHECK_EQUAL(nSuccessCallbacks, 0);
450}
451
452BOOST_AUTO_TEST_CASE(FaceDatasetProcess)
453{
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500454 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"),
455 25, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500456 neighbors.insert(neighborA);
457
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500458 Adjacent neighborB("/ndn/neighborB", ndn::FaceUri("udp4://192.168.0.101:6363"),
459 10, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500460 neighbors.insert(neighborB);
461
462 ndn::nfd::FaceStatus payload1;
463 payload1.setFaceId(1)
464 .setRemoteUri("udp4://192.168.0.100:6363");
465 ndn::nfd::FaceStatus payload2;
466 payload2.setFaceId(2)
467 .setRemoteUri("udp4://192.168.0.101:6363");
468 std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload1, payload2};
469
470 nlsr.processFaceDataset(faceStatuses);
Nick Gordond5c1a372016-10-31 13:56:23 -0500471
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600472 AdjacencyList adjList = conf.getAdjacencyList();
Nick Gordond5c1a372016-10-31 13:56:23 -0500473
474 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborA").getFaceId(), payload1.getFaceId());
475 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborB").getFaceId(), payload2.getFaceId());
476}
477
478BOOST_AUTO_TEST_CASE(UnconfiguredNeighbor)
479{
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -0500480 Adjacent neighborA("/ndn/neighborA", ndn::FaceUri("udp4://192.168.0.100:6363"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
Nick Gordond5c1a372016-10-31 13:56:23 -0500481 neighbors.insert(neighborA);
482
483 ndn::nfd::FaceStatus payload;
484 payload.setFaceId(1)
485 .setRemoteUri("udp4://192.168.0.101:6363"); // Note dissimilar Face URI.
486 std::vector<ndn::nfd::FaceStatus> faceStatuses = {payload};
487
488 nlsr.processFaceDataset(faceStatuses);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600489 this->advanceClocks(20_ms, 5);
Nick Gordond5c1a372016-10-31 13:56:23 -0500490
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600491 AdjacencyList adjList = conf.getAdjacencyList();
Nick Gordond5c1a372016-10-31 13:56:23 -0500492
493 BOOST_CHECK_EQUAL(adjList.getAdjacent("/ndn/neighborA").getFaceId(), 0);
494}
495
496BOOST_AUTO_TEST_CASE(FaceDatasetPeriodicFetch)
497{
498 int nNameMatches = 0;
499 ndn::Name datasetPrefix("/localhost/nfd/faces/list");
500 ndn::nfd::CommandOptions options;
501 ndn::time::milliseconds defaultTimeout = options.getTimeout();
502
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500503 int fetchInterval(1);
Nick Gordond5c1a372016-10-31 13:56:23 -0500504 conf.setFaceDatasetFetchInterval(fetchInterval);
505 conf.setFaceDatasetFetchTries(0);
506
Nick Gordond5c1a372016-10-31 13:56:23 -0500507 // Elapse the default timeout time of the interest.
508 this->advanceClocks(defaultTimeout);
509
510 // Check that we have one interest for face list in the sent interests.
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600511 for (const auto& interest : m_face.sentInterests) {
Nick Gordond5c1a372016-10-31 13:56:23 -0500512 if (datasetPrefix.isPrefixOf(interest.getName())) {
513 nNameMatches++;
514 }
515 }
516 BOOST_CHECK_EQUAL(nNameMatches, 1);
517
518 // Elapse the clock by the reschedule time (that we set)
Ashlesh Gawande3909aa12017-07-28 16:01:35 -0500519 this->advanceClocks(ndn::time::seconds(fetchInterval));
Nick Gordond5c1a372016-10-31 13:56:23 -0500520 // Elapse the default timeout on the interest.
521 this->advanceClocks(defaultTimeout);
Nick Gordond5c1a372016-10-31 13:56:23 -0500522
523 // Check that we now have two interests
524 nNameMatches = 0;
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600525 for (const auto& interest : m_face.sentInterests) {
Nick Gordond5c1a372016-10-31 13:56:23 -0500526 if (datasetPrefix.isPrefixOf(interest.getName())) {
527 nNameMatches++;
528 }
529 }
530 BOOST_CHECK_EQUAL(nNameMatches, 2);
531}
532
Vince Lehman09131122014-09-09 17:10:11 -0500533BOOST_AUTO_TEST_SUITE_END()
534
Nick Gordonfad8e252016-08-11 14:21:38 -0500535} // namespace test
536} // namespace nlsr