mgmt: Initial fib manager with support for fib/add-nexthop
fw: Added FaceId to Face conversion method
Linked InternalFace's sendInterest to FibManager's
onFibRequest
refs: #1138
Change-Id: I0b18f2d41c9ba9d8749c586e3553b51a1e8b1269
diff --git a/tests/mgmt/fib-manager.cpp b/tests/mgmt/fib-manager.cpp
new file mode 100644
index 0000000..bbcce4b
--- /dev/null
+++ b/tests/mgmt/fib-manager.cpp
@@ -0,0 +1,210 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "mgmt/fib-manager.hpp"
+#include "fw/forwarder.hpp"
+#include "table/fib.hpp"
+#include "face/face.hpp"
+#include "../face/dummy-face.hpp"
+
+#include <ndn-cpp-dev/management/fib-management-options.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+namespace nfd {
+
+NFD_LOG_INIT("FibManagerTest");
+
+FaceId g_faceCount = 1;
+std::vector<shared_ptr<Face> > g_faces;
+
+shared_ptr<Face>
+getFace(FaceId id)
+{
+ if (g_faces.size() < id)
+ {
+ BOOST_FAIL("Attempted to access invalid FaceId: " << id);
+ }
+ return g_faces[id-1];
+}
+
+BOOST_AUTO_TEST_SUITE(MgmtFibManager)
+
+BOOST_AUTO_TEST_CASE(MalformedCommmand)
+{
+ Fib fib;
+ FibManager manager(fib, &getFace);
+
+ Interest command(manager.getRequestPrefix());
+ manager.onFibRequest(command);
+}
+
+BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+{
+ Fib fib;
+ FibManager manager(fib, &getFace);
+
+ Name commandName(manager.getRequestPrefix());
+ commandName.append("unsupported");
+
+ Interest command(commandName);
+ manager.onFibRequest(command);
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
+{
+ g_faceCount = 1;
+ g_faces.clear();
+ g_faces.push_back(make_shared<DummyFace>());
+
+ Fib fib;
+
+ FibManager manager(fib, &getFace);
+
+ ndn::FibManagementOptions options;
+ options.setName("/hello");
+ options.setFaceId(1);
+ options.setCost(1);
+
+ Block encodedOptions(options.wireEncode());
+
+ Name commandName(manager.getRequestPrefix());
+ commandName.append("add-nexthop");
+ commandName.append(encodedOptions);
+
+ Interest command(commandName);
+ manager.onFibRequest(command);
+
+ shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
+
+ if (entry)
+ {
+ const fib::NextHopList& hops = entry->getNextHops();
+ BOOST_REQUIRE(hops.size() == 1);
+ // BOOST_CHECK(hops[0].getFace()->getFaceId() == 1);
+ BOOST_CHECK(hops[0].getCost() == 1);
+ }
+ else
+ {
+ BOOST_FAIL("Failed to find expected fib entry");
+ }
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
+{
+ g_faceCount = 1;
+ g_faces.clear();
+ g_faces.push_back(make_shared<DummyFace>());
+ g_faces.push_back(make_shared<DummyFace>());
+
+ Fib fib;
+
+ FibManager manager(fib, &getFace);
+
+ // Add faces with cost == FaceID for the name /hello
+ // This test assumes:
+ // FaceIDs are assigned from 1 to N
+ // Faces are store sequentially in the NextHopList
+ // NextHopList supports random access
+
+ for (int i = 1; i <= 2; i++)
+ {
+ ndn::FibManagementOptions options;
+ options.setName("/hello");
+ options.setFaceId(i);
+ options.setCost(i);
+
+ Block encodedOptions(options.wireEncode());
+
+ Name commandName(manager.getRequestPrefix());
+ commandName.append("add-nexthop");
+ commandName.append(encodedOptions);
+
+ Interest command(commandName);
+ manager.onFibRequest(command);
+
+ shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
+
+ if (entry)
+ {
+ const fib::NextHopList& hops = entry->getNextHops();
+ for (int j = 1; j <= i; j++)
+ {
+ BOOST_REQUIRE(hops.size() == i);
+ // BOOST_CHECK(hops[j-1].getFace()->getFaceId() == j);
+ BOOST_CHECK(hops[j-1].getCost() == j);
+ }
+ }
+ else
+ {
+ BOOST_FAIL("Failed to find expected fib entry");
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
+{
+ g_faceCount = 1;
+ g_faces.clear();
+ g_faces.push_back(make_shared<DummyFace>());
+
+ Fib fib;
+
+ FibManager manager(fib, &getFace);
+
+ ndn::FibManagementOptions options;
+ options.setName("/hello");
+ options.setFaceId(1);
+
+ {
+ options.setCost(1);
+
+ Block encodedOptions(options.wireEncode());
+
+ Name commandName(manager.getRequestPrefix());
+ commandName.append("add-nexthop");
+ commandName.append(encodedOptions);
+
+ Interest command(commandName);
+ manager.onFibRequest(command);
+ }
+
+ {
+ options.setCost(2);
+
+ Block encodedOptions(options.wireEncode());
+
+ Name commandName(manager.getRequestPrefix());
+ commandName.append("add-nexthop");
+ commandName.append(encodedOptions);
+
+ Interest command(commandName);
+ manager.onFibRequest(command);
+ }
+
+ shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
+
+ // Add faces with cost == FaceID for the name /hello
+ // This test assumes:
+ // FaceIDs are assigned from 1 to N
+ // Faces are store sequentially in the NextHopList
+ // NextHopList supports random access
+ if (entry)
+ {
+ const fib::NextHopList& hops = entry->getNextHops();
+ BOOST_REQUIRE(hops.size() == 1);
+ // BOOST_CHECK(hops[0].getFace()->getFaceId() == 1);
+ BOOST_CHECK(hops[0].getCost() == 2);
+ }
+ else
+ {
+ BOOST_FAIL("Failed to find expected fib entry");
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace nfd
diff --git a/tests/mgmt/internal-face.cpp b/tests/mgmt/internal-face.cpp
index 0ece5b6..861ca97 100644
--- a/tests/mgmt/internal-face.cpp
+++ b/tests/mgmt/internal-face.cpp
@@ -5,6 +5,9 @@
*/
#include "mgmt/internal-face.hpp"
+#include "mgmt/fib-manager.hpp"
+#include "table/fib.hpp"
+
#include <boost/test/unit_test.hpp>
@@ -12,16 +15,29 @@
BOOST_AUTO_TEST_SUITE(MgmtInternalFace)
+shared_ptr<Face>
+getFace(FaceId id)
+{
+ return shared_ptr<Face>();
+}
+
BOOST_AUTO_TEST_CASE(ValidPrefixRegistration)
{
- InternalFace internal;
- Interest regInterest("/localhost/nfd/prefixreg/hello/world");
+ Fib fib;
+ FibManager manager(fib, &getFace);
+ InternalFace internal(manager);
+
+ Name regName(manager.getRequestPrefix());
+ regName.append("hello").append("world");
+ Interest regInterest(regName);
internal.sendInterest(regInterest);
}
BOOST_AUTO_TEST_CASE(InvalidPrefixRegistration)
{
- InternalFace internal;
+ Fib fib;
+ FibManager manager(fib, &getFace);
+ InternalFace internal(manager);
Interest nonRegInterest("/hello/world");
internal.sendInterest(nonRegInterest);
}