src: decouple classes from Nlsr object
refs: #1952, #2803, #3960, #4288
Change-Id: Ibe3ac3820f11e8107ee4b13e510d53c27467a6cb
diff --git a/tests/route/test-fib-entry.cpp b/tests/route/test-fib-entry.cpp
new file mode 100644
index 0000000..e38986a
--- /dev/null
+++ b/tests/route/test-fib-entry.cpp
@@ -0,0 +1,47 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+
+#include "route/fib-entry.hpp"
+#include "route/nexthop-list.hpp"
+
+#include <ndn-cxx/util/time.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestFibEntry)
+
+BOOST_AUTO_TEST_CASE(FibEntryConstructorAndGetters)
+{
+ FibEntry fe1("next1");
+
+ BOOST_CHECK_EQUAL(fe1.getName(), "next1");
+ BOOST_CHECK_EQUAL(fe1.getSeqNo(), 1); // Initial Seq No.
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-fib.cpp b/tests/route/test-fib.cpp
new file mode 100644
index 0000000..2e975e8
--- /dev/null
+++ b/tests/route/test-fib.cpp
@@ -0,0 +1,338 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ **/
+
+#include "route/fib.hpp"
+#include "../test-common.hpp"
+#include "../control-commands.hpp"
+#include "adjacency-list.hpp"
+#include "conf-parameter.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace nlsr {
+namespace test {
+
+using std::shared_ptr;
+
+class FibFixture : public UnitTestTimeFixture
+{
+public:
+ FibFixture()
+ : face(std::make_shared<ndn::util::DummyClientFace>(m_ioService, m_keyChain))
+ , conf(*face)
+ , interests(face->sentInterests)
+ {
+ Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
+ adjacencies.insert(neighbor1);
+
+ Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
+ adjacencies.insert(neighbor2);
+
+ Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
+ adjacencies.insert(neighbor3);
+
+ conf.setMaxFacesPerPrefix(2);
+
+ fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
+ fib->setEntryRefreshTime(1);
+
+ fib->m_faceMap.update(router1FaceUri, router1FaceId);
+ fib->m_faceMap.update(router2FaceUri, router2FaceId);
+ fib->m_faceMap.update(router3FaceUri, router3FaceId);
+ }
+
+public:
+ std::shared_ptr<ndn::util::DummyClientFace> face;
+ std::shared_ptr<Fib> fib;
+
+ AdjacencyList adjacencies;
+ ConfParameter conf;
+ std::vector<ndn::Interest>& interests;
+
+ static const ndn::Name router1Name;
+ static const ndn::Name router2Name;
+ static const ndn::Name router3Name;
+
+ static const std::string router1FaceUri;
+ static const std::string router2FaceUri;
+ static const std::string router3FaceUri;
+
+ static const uint32_t router1FaceId;
+ static const uint32_t router2FaceId;
+ static const uint32_t router3FaceId;
+};
+
+const ndn::Name FibFixture::router1Name = "/ndn/router1";
+const ndn::Name FibFixture::router2Name = "/ndn/router2";
+const ndn::Name FibFixture::router3Name = "/ndn/router3";
+
+const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
+const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
+const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
+
+const uint32_t FibFixture::router1FaceId = 1;
+const uint32_t FibFixture::router2FaceId = 2;
+const uint32_t FibFixture::router3FaceId = 3;
+
+BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
+
+BOOST_AUTO_TEST_CASE(NextHopsAdd)
+{
+ NextHop hop1(router1FaceUri, 10);
+ NextHop hop2(router2FaceUri, 20);
+
+ NexthopList hops;
+ hops.addNextHop(hop1);
+ hops.addNextHop(hop2);
+
+ fib->update("/ndn/name", hops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // Should register faces 1 and 2 for /ndn/name
+ BOOST_REQUIRE_EQUAL(interests.size(), 2);
+
+ ndn::nfd::ControlParameters extractedParameters;
+ ndn::Name::Component verb;
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router1FaceId &&
+ verb == ndn::Name::Component("register"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router2FaceId &&
+ verb == ndn::Name::Component("register"));
+}
+
+
+BOOST_AUTO_TEST_CASE(NextHopsNoChange)
+{
+ NextHop hop1(router1FaceUri, 10);
+ NextHop hop2(router2FaceUri, 20);
+
+ NexthopList oldHops;
+ oldHops.addNextHop(hop1);
+ oldHops.addNextHop(hop2);
+
+ fib->update("/ndn/name", oldHops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ BOOST_REQUIRE_EQUAL(interests.size(), 2);
+ interests.clear();
+
+ fib->update("/ndn/name", oldHops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // Should register face 1 and 2 for /ndn/name
+ BOOST_REQUIRE_EQUAL(interests.size(), 2);
+
+ ndn::nfd::ControlParameters extractedParameters;
+ ndn::Name::Component verb;
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router1FaceId &&
+ verb == ndn::Name::Component("register"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router2FaceId &&
+ verb == ndn::Name::Component("register"));
+}
+
+BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
+{
+ NextHop hop1(router1FaceUri, 10);
+ NextHop hop2(router2FaceUri, 20);
+
+ NexthopList oldHops;
+ oldHops.addNextHop(hop1);
+ oldHops.addNextHop(hop2);
+
+ fib->update("/ndn/name", oldHops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ BOOST_REQUIRE_EQUAL(interests.size(), 2);
+ interests.clear();
+
+ NexthopList empty;
+
+ fib->update("/ndn/name", empty);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // Should unregister faces 1 and 2 for /ndn/name
+ BOOST_CHECK_EQUAL(interests.size(), 2);
+
+ ndn::nfd::ControlParameters extractedParameters;
+ ndn::Name::Component verb;
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router1FaceId &&
+ verb == ndn::Name::Component("unregister"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router2FaceId &&
+ verb == ndn::Name::Component("unregister"));
+}
+
+BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
+{
+ NextHop hop1(router1FaceUri, 10);
+ NextHop hop2(router2FaceUri, 20);
+ NextHop hop3(router3FaceUri, 30);
+
+ NexthopList hops;
+ hops.addNextHop(hop1);
+ hops.addNextHop(hop2);
+ hops.addNextHop(hop3);
+
+ fib->update("/ndn/name", hops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // Should only register faces 1 and 2 for /ndn/name
+ BOOST_CHECK_EQUAL(interests.size(), 2);
+
+ ndn::nfd::ControlParameters extractedParameters;
+ ndn::Name::Component verb;
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router1FaceId &&
+ verb == ndn::Name::Component("register"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router2FaceId &&
+ verb == ndn::Name::Component("register"));
+}
+
+BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
+{
+ NextHop hop1(router1FaceUri, 10);
+ NextHop hop2(router2FaceUri, 20);
+
+ NexthopList hops;
+ hops.addNextHop(hop1);
+ hops.addNextHop(hop2);
+
+ fib->update("/ndn/name", hops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // FIB
+ // Name NextHops
+ // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
+ BOOST_REQUIRE_EQUAL(interests.size(), 2);
+ interests.clear();
+
+ // Routing table is recalculated; a new more optimal path is found
+ NextHop hop3(router3FaceUri, 5);
+ hops.addNextHop(hop3);
+
+ fib->update("/ndn/name", hops);
+ face->processEvents(ndn::time::milliseconds(-1));
+
+ // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
+ // unregistered. Face 1 will also be re-registered.
+ //
+ // FIB
+ // Name NextHops
+ // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
+
+ BOOST_CHECK_EQUAL(interests.size(), 3);
+
+ ndn::nfd::ControlParameters extractedParameters;
+ ndn::Name::Component verb;
+ std::vector<ndn::Interest>::iterator it = interests.begin();
+
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router3FaceId &&
+ verb == ndn::Name::Component("register"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router1FaceId &&
+ verb == ndn::Name::Component("register"));
+
+ ++it;
+ extractRibCommandParameters(*it, verb, extractedParameters);
+
+ BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
+ extractedParameters.getFaceId() == router2FaceId &&
+ verb == ndn::Name::Component("unregister"));
+}
+
+BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
+{
+ ndn::Name name1("/name/1");
+ FibEntry fe(name1);
+ fib->m_table.emplace(name1, fe);
+ int origSeqNo = fe.getSeqNo();
+
+ fib->scheduleEntryRefresh(fe,
+ [&] (FibEntry& entry) {
+ BOOST_CHECK_EQUAL(origSeqNo + 1, entry.getSeqNo());
+ });
+ this->advanceClocks(ndn::time::milliseconds(10), 1);
+}
+
+BOOST_AUTO_TEST_CASE(ShouldNotRefreshNeighborRoute) // #4799
+{
+ NextHop hop1;
+ hop1.setConnectingFaceUri(router1FaceUri);
+
+ NexthopList hops;
+ hops.addNextHop(hop1);
+
+ // Simulate update for this neighbor from name prefix table
+ fib->update(router1Name, hops);
+ this->advanceClocks(ndn::time::seconds(1));
+
+ // Should not send the register interest
+ BOOST_CHECK_EQUAL(face->sentInterests.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-map-entry.cpp b/tests/route/test-map-entry.cpp
new file mode 100644
index 0000000..234e5a6
--- /dev/null
+++ b/tests/route/test-map-entry.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019 , The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+#include "route/map.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestMapEntry)
+
+BOOST_AUTO_TEST_CASE(MapEntryConstructorAndGetters)
+{
+ std::string rtr = "r0";
+
+ MapEntry me1(rtr, 1);
+
+ BOOST_CHECK_EQUAL(me1.getRouter(), "r0");
+
+ BOOST_CHECK_EQUAL(me1.getMappingNumber(), 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-map.cpp b/tests/route/test-map.cpp
new file mode 100644
index 0000000..a324b6e
--- /dev/null
+++ b/tests/route/test-map.cpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+#include "route/map.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestMap)
+
+BOOST_AUTO_TEST_CASE(MapAddElementAndSize)
+{
+ Map map1;
+
+ std::string router1 = "r1";
+ std::string router2 = "r2";
+
+ map1.addEntry(router1);
+ map1.addEntry(router2);
+
+ BOOST_CHECK_EQUAL(map1.getMapSize(), 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-name-prefix-table-entry.cpp b/tests/route/test-name-prefix-table-entry.cpp
new file mode 100644
index 0000000..478d4bd
--- /dev/null
+++ b/tests/route/test-name-prefix-table-entry.cpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+#include "route/name-prefix-table-entry.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestNpte)
+
+BOOST_AUTO_TEST_CASE(NpteConstructorAndNamePrefix)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis.edu/cs");
+
+ BOOST_CHECK_EQUAL(npte1.getNamePrefix(), "/ndn/memphis.edu/cs");
+}
+
+BOOST_AUTO_TEST_CASE(AddRoutingTableEntry)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr1");
+ RoutingTablePoolEntry rtpe1("/ndn/memphis/rtr2", 0);
+ std::shared_ptr<RoutingTablePoolEntry> rtpePtr
+ = std::make_shared<RoutingTablePoolEntry>(rtpe1);
+
+ BOOST_CHECK_EQUAL(npte1.m_rteList.size(), 0);
+ npte1.addRoutingTableEntry(rtpePtr);
+ BOOST_CHECK_EQUAL(npte1.m_rteList.size(), 1);
+
+ std::list<std::shared_ptr<RoutingTablePoolEntry>>::iterator itr =
+ std::find(npte1.m_rteList.begin(),
+ npte1.m_rteList.end(),
+ rtpePtr);
+
+ BOOST_CHECK_EQUAL(rtpePtr, *itr);
+}
+
+BOOST_AUTO_TEST_CASE(RemoveRoutingTableEntry)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr1");
+ RoutingTablePoolEntry rtpe1("/ndn/memphis/rtr2", 0);
+ std::shared_ptr<RoutingTablePoolEntry> rtpePtr
+ = std::make_shared<RoutingTablePoolEntry>(rtpe1);
+
+ npte1.addRoutingTableEntry(rtpePtr);
+ npte1.removeRoutingTableEntry(rtpePtr);
+
+ int count = 0;
+ for (auto&& rte : npte1.m_rteList) {
+ if (*rte == rtpe1) {
+ count++;
+ }
+ }
+
+ BOOST_CHECK_EQUAL(count, 0);
+}
+
+BOOST_AUTO_TEST_CASE(EqualsOperatorTwoObj)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr1");
+ NamePrefixTableEntry npte2("/ndn/memphis/rtr1");
+
+ BOOST_CHECK_EQUAL(npte1, npte2);
+}
+
+BOOST_AUTO_TEST_CASE(EqualsOperatorOneObjOneName)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr1");
+
+ BOOST_CHECK_EQUAL(npte1, "/ndn/memphis/rtr1");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-name-prefix-table.cpp b/tests/route/test-name-prefix-table.cpp
new file mode 100644
index 0000000..947f8e1
--- /dev/null
+++ b/tests/route/test-name-prefix-table.cpp
@@ -0,0 +1,312 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California,
+ * Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "route/name-prefix-table.hpp"
+#include "nlsr.hpp"
+#include "../test-common.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace nlsr {
+namespace test {
+
+class NamePrefixTableFixture : public UnitTestTimeFixture
+{
+public:
+ NamePrefixTableFixture()
+ : face(m_ioService, m_keyChain)
+ , conf(face)
+ , nlsr(face, m_keyChain, conf)
+ , lsdb(nlsr.m_lsdb)
+ , npt(nlsr.m_namePrefixTable)
+ {
+ }
+
+public:
+ ndn::util::DummyClientFace face;
+ ConfParameter conf;
+ Nlsr nlsr;
+
+ Lsdb& lsdb;
+ NamePrefixTable& npt;
+};
+
+BOOST_AUTO_TEST_SUITE(TestNamePrefixTable)
+
+BOOST_FIXTURE_TEST_CASE(Bupt, NamePrefixTableFixture)
+{
+ conf.setNetwork("/ndn");
+ conf.setSiteName("/router");
+ conf.setRouterName("/a");
+ conf.buildRouterPrefix();
+
+ RoutingTable& routingTable = nlsr.m_routingTable;
+ routingTable.setRoutingCalcInterval(0);
+
+ Adjacent thisRouter(conf.getRouterPrefix(), ndn::FaceUri("udp4://10.0.0.1"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
+
+ ndn::Name buptRouterName("/ndn/cn/edu/bupt/%C1.Router/bupthub");
+ Adjacent bupt(buptRouterName, ndn::FaceUri("udp4://10.0.0.2"), 0, Adjacent::STATUS_ACTIVE, 0, 0);
+
+ // This router's Adjacency LSA
+ conf.getAdjacencyList().insert(bupt);
+ AdjLsa thisRouterAdjLsa(thisRouter.getName(), 1,
+ ndn::time::system_clock::now() + ndn::time::seconds::max(),
+ 2,
+ conf.getAdjacencyList());
+
+ lsdb.installAdjLsa(thisRouterAdjLsa);
+
+ // BUPT Adjacency LSA
+ AdjacencyList buptAdjacencies;
+ buptAdjacencies.insert(thisRouter);
+ AdjLsa buptAdjLsa(buptRouterName, 1,
+ ndn::time::system_clock::now() + ndn::time::seconds(5),
+ 0 , buptAdjacencies);
+
+ lsdb.installAdjLsa(buptAdjLsa);
+
+ // BUPT Name LSA
+ ndn::Name buptAdvertisedName("/ndn/cn/edu/bupt");
+
+ NamePrefixList buptNames{buptAdvertisedName};
+
+ NameLsa buptNameLsa(buptRouterName, 1, ndn::time::system_clock::now(),
+ buptNames);
+
+ lsdb.installNameLsa(buptNameLsa);
+
+ // Advance clocks to expire LSAs
+ this->advanceClocks(ndn::time::seconds(15));
+
+ // LSA expirations should cause NPT entries to be completely removed
+ NamePrefixTable::const_iterator it = npt.begin();
+ BOOST_REQUIRE(it == npt.end());
+
+ // Install new name LSA
+ NameLsa buptNewNameLsa(buptRouterName, 12,
+ ndn::time::system_clock::now() + ndn::time::seconds(3600),
+ buptNames);
+
+ lsdb.installNameLsa(buptNewNameLsa);
+
+ this->advanceClocks(ndn::time::seconds(1));
+
+ // Install new adjacency LSA
+ AdjLsa buptNewAdjLsa(buptRouterName, 12,
+ ndn::time::system_clock::now() + ndn::time::seconds(3600),
+ 0, buptAdjacencies);
+ lsdb.installAdjLsa(buptNewAdjLsa);
+
+ this->advanceClocks(ndn::time::seconds(1));
+
+ // Each NPT entry should have a destination router
+ it = npt.begin();
+ BOOST_REQUIRE_EQUAL((*it)->getNamePrefix(), buptRouterName);
+ BOOST_REQUIRE_EQUAL((*it)->getRteList().size(), 1);
+ BOOST_CHECK_EQUAL((*(*it)->getRteList().begin())->getDestination(), buptRouterName);
+
+ ++it;
+ BOOST_REQUIRE_EQUAL((*it)->getNamePrefix(), buptAdvertisedName);
+ BOOST_REQUIRE_EQUAL((*it)->getRteList().size(), 1);
+ BOOST_CHECK_EQUAL((*(*it)->getRteList().begin())->getDestination(), buptRouterName);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddEntryToPool, NamePrefixTableFixture)
+{
+ RoutingTablePoolEntry rtpe1("router1");
+
+ npt.addRtpeToPool(rtpe1);
+
+ BOOST_CHECK_EQUAL(npt.m_rtpool.size(), 1);
+ BOOST_CHECK_EQUAL(*(npt.m_rtpool.find("router1")->second), rtpe1);
+}
+
+BOOST_FIXTURE_TEST_CASE(RemoveEntryFromPool, NamePrefixTableFixture)
+{
+ RoutingTablePoolEntry rtpe1("router1", 0);
+ std::shared_ptr<RoutingTablePoolEntry> rtpePtr = npt.addRtpeToPool(rtpe1);
+
+ npt.addRtpeToPool(rtpe1);
+
+ npt.deleteRtpeFromPool(rtpePtr);
+
+ BOOST_CHECK_EQUAL(npt.m_rtpool.size(), 0);
+ BOOST_CHECK_EQUAL(npt.m_rtpool.count("router1"), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRoutingEntryToNptEntry, NamePrefixTableFixture)
+{
+ RoutingTablePoolEntry rtpe1("/ndn/memphis/rtr1", 0);
+ std::shared_ptr<RoutingTablePoolEntry> rtpePtr = npt.addRtpeToPool(rtpe1);
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr2");
+
+ npt.addEntry("/ndn/memphis/rtr2", "/ndn/memphis/rtr1");
+
+ NamePrefixTable::NptEntryList::iterator nItr =
+ std::find_if(npt.m_table.begin(),
+ npt.m_table.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry->getNamePrefix() == npte1.getNamePrefix();
+ });
+
+ std::list<std::shared_ptr<RoutingTablePoolEntry>> rtpeList = (*nItr)->getRteList();
+ std::list<std::shared_ptr<RoutingTablePoolEntry>>::iterator rItr =
+ std::find(rtpeList.begin(),
+ rtpeList.end(),
+ rtpePtr);
+ BOOST_CHECK_EQUAL(**rItr, *rtpePtr);
+}
+
+BOOST_FIXTURE_TEST_CASE(RemoveRoutingEntryFromNptEntry, NamePrefixTableFixture)
+{
+ RoutingTablePoolEntry rtpe1("/ndn/memphis/rtr1", 0);
+
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr2");
+ npt.m_table.push_back(make_shared<NamePrefixTableEntry>(npte1));
+
+ npt.addEntry("/ndn/memphis/rtr2", "/ndn/memphis/rtr1");
+ npt.addEntry("/ndn/memphis/rtr2", "/ndn/memphis/altrtr");
+
+ npt.removeEntry("/ndn/memphis/rtr2", "/ndn/memphis/rtr1");
+
+ NamePrefixTable::NptEntryList::iterator nItr =
+ std::find_if(npt.m_table.begin(),
+ npt.m_table.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry->getNamePrefix() == npte1.getNamePrefix();
+ });
+
+ std::list<std::shared_ptr<RoutingTablePoolEntry>> rtpeList = (*nItr)->getRteList();
+
+ BOOST_CHECK_EQUAL(rtpeList.size(), 1);
+ BOOST_CHECK_EQUAL(npt.m_rtpool.size(), 1);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddNptEntryPtrToRoutingEntry, NamePrefixTableFixture)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr2");
+ npt.m_table.push_back(make_shared<NamePrefixTableEntry>(npte1));
+
+ npt.addEntry("/ndn/memphis/rtr2", "/ndn/memphis/rtr1");
+
+ NamePrefixTable::NptEntryList::iterator nItr =
+ std::find_if(npt.m_table.begin(),
+ npt.m_table.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry->getNamePrefix() == npte1.getNamePrefix();
+ });
+
+ std::list<std::shared_ptr<RoutingTablePoolEntry>> rtpeList = (*nItr)->getRteList();
+
+ BOOST_CHECK_EQUAL(rtpeList.size(), 1);
+
+ auto& namePrefixPtrs = rtpeList.front()->namePrefixTableEntries;
+
+ auto nptIterator = namePrefixPtrs.find(npte1.getNamePrefix());
+ BOOST_REQUIRE(nptIterator != namePrefixPtrs.end());
+ auto nptSharedPtr = nptIterator->second.lock();
+ BOOST_CHECK_EQUAL(*nptSharedPtr, npte1);
+}
+
+BOOST_FIXTURE_TEST_CASE(RemoveNptEntryPtrFromRoutingEntry, NamePrefixTableFixture)
+{
+ NamePrefixTableEntry npte1("/ndn/memphis/rtr1");
+ NamePrefixTableEntry npte2("/ndn/memphis/rtr2");
+ RoutingTableEntry rte1("/ndn/memphis/destination1");
+ npt.m_table.push_back(make_shared<NamePrefixTableEntry>(npte1));
+ npt.m_table.push_back(make_shared<NamePrefixTableEntry>(npte2));
+
+ npt.addEntry(npte1.getNamePrefix(), rte1.getDestination());
+ // We have to add two entries, otherwise the routing pool entry will be deleted.
+ npt.addEntry(npte2.getNamePrefix(), rte1.getDestination());
+ npt.removeEntry(npte2.getNamePrefix(), rte1.getDestination());
+
+ NamePrefixTable::NptEntryList::iterator nItr =
+ std::find_if(npt.m_table.begin(),
+ npt.m_table.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry->getNamePrefix() == npte1.getNamePrefix();
+ });
+
+ std::list<std::shared_ptr<RoutingTablePoolEntry>> rtpeList = (*nItr)->getRteList();
+
+ BOOST_CHECK_EQUAL(rtpeList.size(), 1);
+
+ auto& namePrefixPtrs = rtpeList.front()->namePrefixTableEntries;
+
+ // We should have removed the second one
+ BOOST_CHECK_EQUAL(namePrefixPtrs.size(), 1);
+
+ auto nptIterator = namePrefixPtrs.find(npte1.getNamePrefix());
+
+ BOOST_REQUIRE(nptIterator != namePrefixPtrs.end());
+ auto nptSharedPtr = nptIterator->second.lock();
+ BOOST_CHECK_EQUAL(*nptSharedPtr, npte1);
+}
+
+BOOST_FIXTURE_TEST_CASE(RoutingTableUpdate, NamePrefixTableFixture)
+{
+ RoutingTable& routingTable = nlsr.m_routingTable;
+ const ndn::Name destination = ndn::Name{"/ndn/destination1"};
+ NextHop hop1{"upd4://10.0.0.1", 0};
+ NextHop hop2{"udp4://10.0.0.2", 1};
+ NextHop hop3{"udp4://10.0.0.3", 2};
+ const NamePrefixTableEntry entry1{"/ndn/router1"};
+ npt.addEntry(entry1.getNamePrefix(), destination);
+
+ routingTable.addNextHop(destination, hop1);
+ routingTable.addNextHop(destination, hop2);
+
+ npt.updateWithNewRoute(routingTable.m_rTable);
+
+ // At this point the NamePrefixTableEntry should have two NextHops.
+ auto nameIterator = std::find_if(npt.begin(), npt.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry1.getNamePrefix() == entry->getNamePrefix();
+ });
+ BOOST_REQUIRE(nameIterator != npt.end());
+
+ auto iterator = npt.m_rtpool.find(destination);
+ BOOST_REQUIRE(iterator != npt.m_rtpool.end());
+ auto nextHops = (iterator->second)->getNexthopList();
+ BOOST_CHECK_EQUAL(nextHops.size(), 2);
+
+ // Add the other NextHop
+ routingTable.addNextHop(destination, hop3);
+ npt.updateWithNewRoute(routingTable.m_rTable);
+
+ // At this point the NamePrefixTableEntry should have three NextHops.
+ nameIterator = std::find_if(npt.begin(), npt.end(),
+ [&] (const std::shared_ptr<NamePrefixTableEntry>& entry) {
+ return entry1.getNamePrefix() == entry->getNamePrefix();
+ });
+ BOOST_REQUIRE(nameIterator != npt.end());
+ iterator = npt.m_rtpool.find(destination);
+ BOOST_REQUIRE(iterator != npt.m_rtpool.end());
+ nextHops = (iterator->second)->getNexthopList();
+ BOOST_CHECK_EQUAL(nextHops.size(), 3);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-nexthop-list.cpp b/tests/route/test-nexthop-list.cpp
new file mode 100644
index 0000000..ed5bf0d
--- /dev/null
+++ b/tests/route/test-nexthop-list.cpp
@@ -0,0 +1,187 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California,
+ * Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "route/nexthop-list.hpp"
+#include "route/nexthop.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestNhl)
+
+BOOST_AUTO_TEST_CASE(NhlAddNextHop)
+{
+ NextHop np1;
+
+ NexthopList nhl1;
+
+ nhl1.addNextHop(np1);
+ BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)1);
+
+ nhl1.removeNextHop(np1);
+ BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)0);
+}
+
+BOOST_AUTO_TEST_CASE(LinkStateRemoveNextHop)
+{
+ NextHop hop1;
+ hop1.setRouteCost(12.34);
+
+ NexthopList hopList;
+ hopList.addNextHop(hop1);
+
+ NextHop hop2;
+ hop2.setRouteCost(13.01);
+
+ BOOST_REQUIRE_EQUAL(hopList.size(), 1);
+
+ hopList.removeNextHop(hop2);
+ BOOST_CHECK_EQUAL(hopList.size(), 1);
+
+ hopList.removeNextHop(hop1);
+ BOOST_CHECK_EQUAL(hopList.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(HyperbolicRemoveNextHop)
+{
+ NextHop hop1;
+ hop1.setHyperbolic(true);
+ hop1.setRouteCost(12.34);
+
+ NexthopList hopList;
+ hopList.addNextHop(hop1);
+
+ NextHop hop2;
+ hop2.setHyperbolic(true);
+ hop2.setRouteCost(12.35);
+
+ BOOST_REQUIRE_EQUAL(hopList.size(), 1);
+
+ hopList.removeNextHop(hop2);
+ BOOST_CHECK_EQUAL(hopList.size(), 1);
+
+ hopList.removeNextHop(hop1);
+ BOOST_CHECK_EQUAL(hopList.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(TieBreaker)
+{
+ // equal-cost hops are sorted lexicographically
+ NextHop hopA;
+ hopA.setRouteCost(25);
+ hopA.setConnectingFaceUri("AAAZZ");
+
+ NextHop hopZ;
+ hopZ.setRouteCost(25);
+ hopZ.setConnectingFaceUri("ZZA");
+
+ NexthopList list;
+ list.addNextHop(hopA);
+ list.addNextHop(hopZ);
+
+ NexthopList::iterator it = list.begin();
+ BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());
+
+ list.reset();
+ list.addNextHop(hopZ);
+ list.addNextHop(hopA);
+
+ it = list.begin();
+ BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());
+
+
+ // equal-cost and lexicographically equal hops are sorted by the length of their face uris
+ NextHop longUriHop;
+ longUriHop.setRouteCost(25);
+ longUriHop.setConnectingFaceUri("AAAAAA");
+
+ NextHop shortUriHop;
+ shortUriHop.setRouteCost(25);
+ shortUriHop.setConnectingFaceUri("AAA");
+
+ list.reset();
+ list.addNextHop(longUriHop);
+ list.addNextHop(shortUriHop);
+
+ it = list.begin();
+ BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), shortUriHop.getConnectingFaceUri());
+}
+
+BOOST_AUTO_TEST_CASE(SortOnAddAndRemove)
+{
+ NexthopList list;
+
+ NextHop hopA("A", 10);
+ NextHop hopB("B", 5);
+ NextHop hopC("C", 25);
+
+ list.addNextHop(hopA);
+ list.addNextHop(hopB);
+ list.addNextHop(hopC);
+
+ BOOST_REQUIRE_EQUAL(list.size(), 3);
+
+ double lastCost = 0;
+ for (const auto& hop : list) {
+ BOOST_CHECK(hop.getRouteCost() > lastCost);
+ lastCost = hop.getRouteCost();
+ }
+
+ // removing a hop keep the list sorted
+ list.removeNextHop(hopA);
+
+ BOOST_REQUIRE_EQUAL(list.size(), 2);
+
+ lastCost = 0;
+ for (const auto& hop : list) {
+ BOOST_CHECK(hop.getRouteCost() > lastCost);
+ lastCost = hop.getRouteCost();
+ }
+}
+
+/* If there are two NextHops going to the same neighbor, then the list
+ should always select the one with the cheaper cost. This would be
+ caused by a Name being advertised by two different routers, which
+ are reachable through the same neighbor.
+ */
+BOOST_AUTO_TEST_CASE(UseCheaperNextHop)
+{
+ NexthopList list;
+
+ NextHop hopA("udp4://10.0.0.1:6363", 10);
+ NextHop hopB("udp4://10.0.0.1:6363", 5);
+
+ list.addNextHop(hopA);
+ list.addNextHop(hopB);
+
+ BOOST_REQUIRE_EQUAL(list.size(), 1);
+
+ for (const auto& hop : list) {
+ BOOST_CHECK_EQUAL(hop, hopB);
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-nexthop.cpp b/tests/route/test-nexthop.cpp
new file mode 100644
index 0000000..12be825
--- /dev/null
+++ b/tests/route/test-nexthop.cpp
@@ -0,0 +1,109 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+#include "route/nexthop.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestNexthop)
+
+double
+getHyperbolicAdjustedDecimal(unsigned int i)
+{
+ return static_cast<double>(i)/(10*NextHop::HYPERBOLIC_COST_ADJUSTMENT_FACTOR);
+}
+
+uint64_t
+applyHyperbolicFactorAndRound(double d)
+{
+ return round(NextHop::HYPERBOLIC_COST_ADJUSTMENT_FACTOR*d);
+}
+
+BOOST_AUTO_TEST_CASE(LinkStateSetAndGet)
+{
+ NextHop hop1;
+ hop1.setConnectingFaceUri("udp://test/uri");
+ hop1.setRouteCost(12.34);
+
+ BOOST_CHECK_EQUAL(hop1.getConnectingFaceUri(), "udp://test/uri");
+ BOOST_CHECK_EQUAL(hop1.getRouteCost(), 12.34);
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), 12);
+
+ NextHop hop2;
+
+ hop2.setRouteCost(12.34);
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), hop2.getRouteCostAsAdjustedInteger());
+}
+
+BOOST_AUTO_TEST_CASE(HyperbolicSetAndGet)
+{
+ NextHop hop1;
+ hop1.setHyperbolic(true);
+ hop1.setConnectingFaceUri("udp://test/uri");
+ hop1.setRouteCost(12.34);
+
+ BOOST_CHECK_EQUAL(hop1.getConnectingFaceUri(), "udp://test/uri");
+ BOOST_CHECK_EQUAL(hop1.getRouteCost(), 12.34);
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), applyHyperbolicFactorAndRound(12.34));
+
+ NextHop hop2;
+ hop2.setHyperbolic(true);
+
+ hop2.setRouteCost(12.34);
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), hop2.getRouteCostAsAdjustedInteger());
+
+ hop2.setRouteCost(12.35);
+ BOOST_CHECK(hop1.getRouteCostAsAdjustedInteger() < hop2.getRouteCostAsAdjustedInteger());
+}
+
+BOOST_AUTO_TEST_CASE(HyperbolicRound)
+{
+ NextHop hop1;
+ hop1.setHyperbolic(true);
+ hop1.setConnectingFaceUri("udp://test/uri");
+ hop1.setRouteCost(1 + getHyperbolicAdjustedDecimal(6));
+
+ BOOST_CHECK_EQUAL(hop1.getConnectingFaceUri(), "udp://test/uri");
+ BOOST_CHECK_EQUAL(hop1.getRouteCost(), 1 + getHyperbolicAdjustedDecimal(6));
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(),
+ applyHyperbolicFactorAndRound((1 + getHyperbolicAdjustedDecimal(6))));
+
+ NextHop hop2;
+ hop2.setHyperbolic(true);
+
+ hop2.setRouteCost(1 + getHyperbolicAdjustedDecimal(6));
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), hop2.getRouteCostAsAdjustedInteger());
+
+ hop2.setRouteCost(1 + getHyperbolicAdjustedDecimal(5));
+ BOOST_CHECK_EQUAL(hop1.getRouteCostAsAdjustedInteger(), hop2.getRouteCostAsAdjustedInteger());
+
+ hop2.setRouteCost(1 + getHyperbolicAdjustedDecimal(4));
+ BOOST_CHECK(hop1.getRouteCostAsAdjustedInteger() > hop2.getRouteCostAsAdjustedInteger());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-routing-table-entry.cpp b/tests/route/test-routing-table-entry.cpp
new file mode 100644
index 0000000..b2ac244
--- /dev/null
+++ b/tests/route/test-routing-table-entry.cpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+#include "route/routing-table-entry.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestRoutingTableEntry)
+
+BOOST_AUTO_TEST_CASE(RoutingTableEntryDestination)
+{
+ RoutingTableEntry rte1("router1");
+
+ BOOST_CHECK_EQUAL(rte1.getDestination(), "router1");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-routing-table-pool-entry.cpp b/tests/route/test-routing-table-pool-entry.cpp
new file mode 100644
index 0000000..444fbbd
--- /dev/null
+++ b/tests/route/test-routing-table-pool-entry.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Nicholas Gordon <nmgordon@memphis.edu>
+ *
+ **/
+#include "route/routing-table-pool-entry.hpp"
+#include "route/nexthop.hpp"
+#include "route/nexthop-list.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+
+namespace test {
+
+BOOST_AUTO_TEST_SUITE(TestRoutingTablePoolEntry)
+
+BOOST_AUTO_TEST_CASE(EqualsOperator)
+{
+ NextHop hop1;
+ hop1.setRouteCost(25);
+ hop1.setConnectingFaceUri("AAA");
+
+ NextHop hop2;
+ hop2.setRouteCost(10);
+ hop2.setConnectingFaceUri("BBB");
+
+ NexthopList nhl1;
+ NexthopList nhl2;
+
+ nhl1.addNextHop(hop1);
+ nhl1.addNextHop(hop2);
+
+ RoutingTablePoolEntry rtpe1("/memphis/ndn/rtr1", 0);
+ RoutingTablePoolEntry rtpe2("/memphis/ndn/rtr1", 0);
+
+ rtpe1.setNexthopList(nhl1);
+ rtpe2.setNexthopList(nhl1);
+
+ BOOST_CHECK_EQUAL(rtpe1, rtpe2);
+}
+
+BOOST_AUTO_TEST_CASE(IncrementEntryUseCount)
+{
+ RoutingTablePoolEntry rtpe1("router1");
+
+ rtpe1.incrementUseCount();
+
+ BOOST_CHECK_EQUAL(rtpe1.getUseCount(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(DecrementEntryUseCountNotZero)
+{
+ RoutingTablePoolEntry rtpe1("router1");
+
+ rtpe1.decrementUseCount();
+
+ BOOST_CHECK_EQUAL(rtpe1.getUseCount(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(DecrementEntryUseCountAtZero)
+{
+ RoutingTablePoolEntry rtpe1("router1");
+
+ rtpe1.decrementUseCount();
+ rtpe1.decrementUseCount();
+
+ BOOST_CHECK_EQUAL(rtpe1.getUseCount(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(UpdateNextHopList)
+{
+ RoutingTablePoolEntry rtpe1("router1");
+ NextHop nh1;
+ NexthopList nhl1;
+
+ nhl1.addNextHop(nh1);
+
+ rtpe1.setNexthopList(nhl1);
+
+ BOOST_CHECK_EQUAL(rtpe1.getNexthopList(), nhl1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
diff --git a/tests/route/test-routing-table.cpp b/tests/route/test-routing-table.cpp
new file mode 100644
index 0000000..cd600f1
--- /dev/null
+++ b/tests/route/test-routing-table.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019, The University of Memphis,
+ * Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * \author Ashlesh Gawande <agawande@memphis.edu>
+ *
+ **/
+
+#include "route/routing-table.hpp"
+#include "nlsr.hpp"
+#include "../test-common.hpp"
+#include "route/routing-table-entry.hpp"
+#include "route/nexthop.hpp"
+#include <boost/test/unit_test.hpp>
+
+namespace nlsr {
+namespace test {
+
+BOOST_FIXTURE_TEST_SUITE(TestRoutingTable, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(RoutingTableAddNextHop)
+{
+ ndn::util::DummyClientFace face;
+ ConfParameter conf(face);
+ ndn::KeyChain keyChain;
+ Nlsr nlsr(face, keyChain, conf);
+
+ RoutingTable rt1(m_scheduler, nlsr.m_fib, nlsr.m_lsdb,
+ nlsr.m_namePrefixTable, conf);
+
+ NextHop nh1;
+ const std::string DEST_ROUTER = "destRouter";
+ rt1.addNextHop(DEST_ROUTER, nh1);
+
+ BOOST_CHECK_EQUAL(rt1.findRoutingTableEntry(DEST_ROUTER)->getDestination(), DEST_ROUTER);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr