| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2014, Regents of the University of California, |
| * Arizona Board of Regents, |
| * Colorado State University, |
| * University Pierre & Marie Curie, Sorbonne University, |
| * Washington University in St. Louis, |
| * Beijing Institute of Technology, |
| * The University of Memphis |
| * |
| * This file is part of NFD (Named Data Networking Forwarding Daemon). |
| * See AUTHORS.md for complete list of NFD authors and contributors. |
| * |
| * NFD 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. |
| * |
| * NFD 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 |
| * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| #include "rib/rib-manager.hpp" |
| #include <ndn-cxx/management/nfd-face-status.hpp> |
| #include "rib/rib-status-publisher-common.hpp" |
| |
| #include "tests/test-common.hpp" |
| #include "tests/limited-io.hpp" |
| #include <ndn-cxx/util/dummy-client-face.hpp> |
| |
| namespace nfd { |
| namespace rib { |
| namespace tests { |
| |
| class RibManagerFixture : public nfd::tests::BaseFixture |
| { |
| public: |
| RibManagerFixture() |
| : COMMAND_PREFIX("/localhost/nfd/rib") |
| , ADD_NEXTHOP_VERB("add-nexthop") |
| , REMOVE_NEXTHOP_VERB("remove-nexthop") |
| { |
| face = ndn::util::makeDummyClientFace(); |
| |
| manager = make_shared<RibManager>(ndn::ref(*face)); |
| manager->registerWithNfd(); |
| |
| face->processEvents(time::milliseconds(1)); |
| face->sentInterests.clear(); |
| } |
| |
| ~RibManagerFixture() |
| { |
| manager.reset(); |
| face.reset(); |
| } |
| |
| void extractParameters(Interest& interest, Name::Component& verb, |
| ControlParameters& extractedParameters) |
| { |
| const Name& name = interest.getName(); |
| verb = name[COMMAND_PREFIX.size()]; |
| const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1]; |
| |
| Block rawParameters = parameterComponent.blockFromValue(); |
| extractedParameters.wireDecode(rawParameters); |
| } |
| |
| void receiveCommandInterest(Name& name, ControlParameters& parameters) |
| { |
| receiveCommandInterest(name.append(parameters.wireEncode())); |
| } |
| |
| void receiveCommandInterest(const Name& name) |
| { |
| Interest command(name); |
| |
| face->receive(command); |
| face->processEvents(time::milliseconds(1)); |
| } |
| |
| public: |
| shared_ptr<RibManager> manager; |
| shared_ptr<ndn::util::DummyClientFace> face; |
| |
| const Name COMMAND_PREFIX; |
| const Name::Component ADD_NEXTHOP_VERB; |
| const Name::Component REMOVE_NEXTHOP_VERB; |
| }; |
| |
| class AuthorizedRibManager : public RibManagerFixture |
| { |
| public: |
| AuthorizedRibManager() |
| { |
| ConfigFile config; |
| manager->setConfigFile(config); |
| |
| const std::string CONFIG_STRING = |
| "rib\n" |
| "{\n" |
| " localhost_security\n" |
| " {\n" |
| " trust-anchor\n" |
| " {\n" |
| " type any\n" |
| " }\n" |
| " }" |
| "}"; |
| |
| config.parse(CONFIG_STRING, true, "test-rib"); |
| } |
| }; |
| |
| typedef RibManagerFixture UnauthorizedRibManager; |
| |
| BOOST_FIXTURE_TEST_SUITE(RibManager, RibManagerFixture) |
| |
| BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager) |
| { |
| Name commandName("/localhost/nfd/rib"); |
| receiveCommandInterest(commandName); |
| // TODO verify error response |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager) |
| { |
| ControlParameters parameters; |
| parameters |
| .setName("/hello") |
| .setFaceId(1) |
| .setCost(10) |
| .setFlags(0) |
| .setOrigin(128) |
| .setExpirationPeriod(ndn::time::milliseconds::max()); |
| |
| Name commandName("/localhost/nfd/rib/register"); |
| |
| receiveCommandInterest(commandName, parameters); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(Register, AuthorizedRibManager) |
| { |
| ControlParameters parameters; |
| parameters |
| .setName("/hello") |
| .setFaceId(1) |
| .setCost(10) |
| .setFlags(0) |
| .setOrigin(128) |
| .setExpirationPeriod(ndn::time::milliseconds::max()); |
| |
| Name commandName("/localhost/nfd/rib/register"); |
| |
| receiveCommandInterest(commandName, parameters); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName()); |
| BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), parameters.getFaceId()); |
| BOOST_CHECK_EQUAL(extractedParameters.getCost(), parameters.getCost()); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(Unregister, AuthorizedRibManager) |
| { |
| ControlParameters addParameters; |
| addParameters |
| .setName("/hello") |
| .setFaceId(1) |
| .setCost(10) |
| .setFlags(0) |
| .setOrigin(128) |
| .setExpirationPeriod(ndn::time::milliseconds::max()); |
| |
| Name registerName("/localhost/nfd/rib/register"); |
| |
| receiveCommandInterest(registerName, addParameters); |
| face->sentInterests.clear(); |
| |
| ControlParameters removeParameters; |
| removeParameters |
| .setName("/hello") |
| .setFaceId(1) |
| .setOrigin(128); |
| |
| Name unregisterName("/localhost/nfd/rib/unregister"); |
| |
| receiveCommandInterest(unregisterName, removeParameters); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName()); |
| BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId()); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager) |
| { |
| ControlParameters parameters; |
| parameters |
| .setName("/hello") |
| .setFaceId(1) |
| .setCost(10) |
| .setFlags(0) |
| .setOrigin(128) |
| .setExpirationPeriod(ndn::time::milliseconds::max()); |
| |
| Name commandName("/localhost/nfd/rib/register"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| |
| receiveCommandInterest(commandName, parameters); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager) |
| { |
| Route route; |
| Name name("/"); |
| route.faceId = 1; |
| route.origin = 128; |
| route.cost = 32; |
| route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE; |
| |
| ControlParameters parameters; |
| parameters |
| .setName(name) |
| .setFaceId(route.faceId) |
| .setOrigin(route.origin) |
| .setCost(route.cost) |
| .setFlags(route.flags) |
| .setExpirationPeriod(ndn::time::milliseconds::max()); |
| |
| Name commandName("/localhost/nfd/rib/register"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| |
| receiveCommandInterest(commandName, parameters); |
| face->sentInterests.clear(); |
| face->sentDatas.clear(); |
| |
| face->receive(Interest("/localhost/nfd/rib/list")); |
| face->processEvents(time::milliseconds(1)); |
| |
| BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1); |
| RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], name, route); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager) |
| { |
| // Register face |
| ControlParameters addParameters; |
| addParameters |
| .setName("/expire") |
| .setFaceId(1) |
| .setCost(10) |
| .setFlags(0) |
| .setOrigin(128) |
| .setExpirationPeriod(ndn::time::milliseconds(500)); |
| |
| Name registerName("/localhost/nfd/rib/register"); |
| |
| receiveCommandInterest(registerName, addParameters); |
| face->sentInterests.clear(); |
| |
| // Unregister face |
| ControlParameters removeParameters; |
| removeParameters |
| .setName("/expire") |
| .setFaceId(1) |
| .setOrigin(128); |
| |
| Name unregisterName("/localhost/nfd/rib/unregister"); |
| |
| receiveCommandInterest(unregisterName, removeParameters); |
| |
| // Reregister face |
| Name reRegisterName("/localhost/nfd/rib/register"); |
| addParameters.setExpirationPeriod(ndn::time::milliseconds::max()); |
| receiveCommandInterest(reRegisterName, addParameters); |
| |
| nfd::tests::LimitedIo limitedIo; |
| limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1)); |
| |
| BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RemoveInvalidFaces, AuthorizedRibManager) |
| { |
| // Register valid face |
| ControlParameters validParameters; |
| validParameters |
| .setName("/test") |
| .setFaceId(1); |
| |
| Name validName("/localhost/nfd/rib/register"); |
| receiveCommandInterest(validName, validParameters); |
| |
| // Register invalid face |
| ControlParameters invalidParameters; |
| invalidParameters |
| .setName("/test") |
| .setFaceId(2); |
| |
| Name invalidName("/localhost/nfd/rib/register"); |
| receiveCommandInterest(invalidName, invalidParameters); |
| |
| BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2); |
| |
| // Receive status with only faceId: 1 |
| ndn::nfd::FaceStatus status; |
| status.setFaceId(1); |
| |
| shared_ptr<Data> data = nfd::tests::makeData("/localhost/nfd/faces/list"); |
| data->setContent(status.wireEncode()); |
| |
| shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>(); |
| buffer->write(reinterpret_cast<const char*>(data->getContent().value()), |
| data->getContent().value_size()); |
| |
| manager->removeInvalidFaces(buffer); |
| |
| // Run scheduler |
| nfd::tests::LimitedIo limitedIo; |
| limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1)); |
| |
| BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1); |
| |
| Rib::const_iterator it = manager->m_managedRib.find("/test"); |
| BOOST_REQUIRE(it != manager->m_managedRib.end()); |
| |
| shared_ptr<RibEntry> entry = it->second; |
| BOOST_CHECK_EQUAL(entry->hasFaceId(1), true); |
| BOOST_CHECK_EQUAL(entry->hasFaceId(2), false); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(LocalHopInherit, AuthorizedRibManager) |
| { |
| using nfd::rib::RibManager; |
| |
| // Simulate NFD response |
| ControlParameters result; |
| result.setFaceId(261); |
| |
| manager->onNrdCommandPrefixAddNextHopSuccess(RibManager::REMOTE_COMMAND_PREFIX, result); |
| |
| // Register route that localhop prefix should inherit |
| ControlParameters parameters; |
| parameters |
| .setName("/localhop/nfd") |
| .setFaceId(262) |
| .setCost(25) |
| .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT); |
| |
| Name commandName("/localhost/nfd/rib/register"); |
| |
| receiveCommandInterest(commandName, parameters); |
| |
| // REMOTE_COMMAND_PREFIX should have its original route and the inherited route |
| auto it = manager->m_managedRib.find(RibManager::REMOTE_COMMAND_PREFIX); |
| |
| BOOST_REQUIRE(it != manager->m_managedRib.end()); |
| const RibEntry::RouteList& inheritedRoutes = (*(it->second)).getInheritedRoutes(); |
| |
| BOOST_CHECK_EQUAL(inheritedRoutes.size(), 1); |
| auto routeIt = inheritedRoutes.begin(); |
| |
| BOOST_CHECK_EQUAL(routeIt->faceId, 262); |
| BOOST_CHECK_EQUAL(routeIt->cost, 25); |
| } |
| |
| BOOST_AUTO_TEST_SUITE_END() |
| |
| } // namespace tests |
| } // namespace rib |
| } // namespace nfd |