| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2014-2015, 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/remote-registrator.hpp" |
| |
| #include "tests/limited-io.hpp" |
| #include "tests/identity-management-fixture.hpp" |
| #include <ndn-cxx/util/dummy-client-face.hpp> |
| |
| namespace nfd { |
| namespace rib { |
| namespace tests { |
| |
| class RemoteRegistratorFixture : public nfd::tests::IdentityManagementFixture |
| , public nfd::tests::UnitTestTimeFixture |
| { |
| public: |
| RemoteRegistratorFixture() |
| : face(ndn::util::makeDummyClientFace(getGlobalIoService())) |
| , controller(make_shared<ndn::nfd::Controller>(std::ref(*face), m_keyChain)) |
| , remoteRegistrator(make_shared<RemoteRegistrator>(std::ref(*controller), |
| m_keyChain, |
| rib)) |
| , COMMAND_PREFIX("/localhop/nfd/rib") |
| , REGISTER_VERB("register") |
| , UNREGISTER_VERB("unregister") |
| { |
| readConfig(); |
| |
| remoteRegistrator->enable(); |
| |
| advanceClocks(time::milliseconds(1)); |
| face->sentInterests.clear(); |
| } |
| |
| void |
| readConfig(bool isSetRetry = false) |
| { |
| ConfigFile config; |
| config.addSectionHandler("remote_register", |
| bind(&RemoteRegistrator::loadConfig, remoteRegistrator, _1)); |
| |
| |
| if (isSetRetry) |
| { |
| const std::string CONFIG_STRING = |
| "remote_register\n" |
| "{\n" |
| " cost 15\n" |
| " timeout 1000\n" |
| " retry 1\n" |
| " refresh_interval 5\n" |
| "}"; |
| |
| config.parse(CONFIG_STRING, true, "test-remote-register"); |
| } |
| else |
| { |
| const std::string CONFIG_STRING = |
| "remote_register\n" |
| "{\n" |
| " cost 15\n" |
| " timeout 100000\n" |
| " retry 0\n" |
| " refresh_interval 5\n" |
| "}"; |
| |
| config.parse(CONFIG_STRING, true, "test-remote-register"); |
| } |
| } |
| |
| void |
| waitForTimeout() |
| { |
| advanceClocks(time::milliseconds(100), time::seconds(1)); |
| } |
| |
| void |
| insertEntryWithIdentity(Name identity, |
| name::Component appName = DEFAULT_APP_NAME, |
| uint64_t faceId = 0) |
| { |
| BOOST_CHECK_EQUAL(addIdentity(identity), true); |
| |
| FaceEntry faceEntry; |
| faceEntry.faceId = faceId; |
| |
| rib.insert(identity.append(appName), faceEntry); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| insertEntryWithoutIdentity(Name identity, |
| name::Component appName = DEFAULT_APP_NAME, |
| uint64_t faceId = 0) |
| { |
| FaceEntry faceEntry; |
| faceEntry.faceId = faceId; |
| |
| rib.insert(identity.append(appName), faceEntry); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| eraseEntryWithIdentity(Name identity, |
| name::Component appName = DEFAULT_APP_NAME, |
| uint64_t faceId = 0) |
| { |
| BOOST_CHECK_EQUAL(addIdentity(identity), true); |
| |
| FaceEntry faceEntry; |
| faceEntry.faceId = faceId; |
| |
| rib.erase(identity.append(appName), faceEntry); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| eraseEntryWithoutIdentity(Name identity, |
| name::Component appName = DEFAULT_APP_NAME, |
| uint64_t faceId = 0) |
| { |
| FaceEntry faceEntry; |
| faceEntry.faceId = faceId; |
| |
| rib.erase(identity.append(appName), faceEntry); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| eraseFace(uint64_t faceId) |
| { |
| rib.erase(faceId); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| connectToHub() |
| { |
| rib.insert(COMMAND_PREFIX, FaceEntry()); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| disconnectToHub() |
| { |
| rib.erase(COMMAND_PREFIX, FaceEntry()); |
| |
| advanceClocks(time::milliseconds(1)); |
| } |
| |
| void |
| extractParameters(Interest& interest, Name::Component& verb, |
| ndn::nfd::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); |
| } |
| |
| public: |
| Rib rib; |
| shared_ptr<ndn::util::DummyClientFace> face; |
| shared_ptr<ndn::nfd::Controller> controller; |
| shared_ptr<RemoteRegistrator> remoteRegistrator; |
| |
| const Name COMMAND_PREFIX; |
| const name::Component REGISTER_VERB; |
| const name::Component UNREGISTER_VERB; |
| |
| static const name::Component DEFAULT_APP_NAME; |
| }; |
| |
| const name::Component RemoteRegistratorFixture::DEFAULT_APP_NAME("app"); |
| |
| BOOST_FIXTURE_TEST_SUITE(RemoteRegistrator, RemoteRegistratorFixture) |
| |
| BOOST_FIXTURE_TEST_CASE(AutoTest, RemoteRegistratorFixture) |
| { |
| BOOST_REQUIRE_EQUAL(1, 1); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterWithoutConnection, RemoteRegistratorFixture) |
| { |
| insertEntryWithIdentity("/remote/register"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterWithoutIdentity, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| insertEntryWithoutIdentity("/remote/register"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterWithHubPrefix, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterWithLocalPrefix, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| insertEntryWithIdentity("/localhost/prefix"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterBasic, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| insertEntryWithIdentity(identity); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterAdvanced, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| Name identityAddRib("/remote/register/rib"); |
| insertEntryWithIdentity(identityAddRib); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterWithRedundantCallback, RemoteRegistratorFixture) |
| { |
| remoteRegistrator->enable(); |
| |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| insertEntryWithIdentity(identity); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RegisterRetry, RemoteRegistratorFixture) |
| { |
| // setRetry |
| readConfig(true); |
| |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| insertEntryWithIdentity(identity); |
| |
| waitForTimeout(); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| Interest& requestFirst = face->sentInterests[0]; |
| Interest& requestSecond = face->sentInterests[1]; |
| |
| ndn::nfd::ControlParameters extractedParametersFirst, extractedParametersSecond; |
| Name::Component verbFirst, verbSecond; |
| extractParameters(requestFirst, verbFirst, extractedParametersFirst); |
| extractParameters(requestSecond, verbSecond, extractedParametersSecond); |
| |
| BOOST_CHECK_EQUAL(verbFirst, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(verbSecond, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParametersFirst.getName(), identity); |
| BOOST_CHECK_EQUAL(extractedParametersSecond.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnregisterWithoutInsert, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| eraseEntryWithIdentity("/remote/register"); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnregisterWithoutConnection, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| disconnectToHub(); |
| |
| Name indentity("/remote/register"); |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(indentity, scheduler::EventId())); |
| |
| eraseEntryWithIdentity(indentity); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnregisterWithoutSuccessfullRegistration, |
| RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| |
| insertEntryWithIdentity(identity); |
| |
| eraseEntryWithIdentity(identity); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1); |
| |
| Interest& request = face->sentInterests[0]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnregisterBasic, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| |
| insertEntryWithIdentity(identity); |
| |
| scheduler::EventId event; |
| |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event)); |
| |
| eraseEntryWithIdentity(identity); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| Interest& request = face->sentInterests[1]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnregisterAdvanced, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identityShort("/remote/register"); |
| Name identityLong("/remote/register/long"); |
| |
| scheduler::EventId eventShort; |
| scheduler::EventId eventLong; |
| |
| insertEntryWithIdentity(identityShort, name::Component("appA")); |
| |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(identityShort, |
| eventShort)); |
| |
| insertEntryWithIdentity(identityShort, name::Component("appB")); |
| |
| insertEntryWithIdentity(identityLong); |
| |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(identityLong, |
| eventLong)); |
| |
| // two registration commands are generated for identityShort and identityLong |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| eraseEntryWithIdentity(identityShort, name::Component("appA")); |
| |
| // no unregistration command is generated as appB also exists |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| eraseEntryWithIdentity(identityShort, name::Component("appB")); |
| |
| // one unregistration command is generated for identityShort |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 3); |
| |
| Interest& request = face->sentInterests[2]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identityShort); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(EraseFace, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| uint64_t faceId = 517; |
| |
| insertEntryWithIdentity(identity, DEFAULT_APP_NAME, faceId); |
| |
| scheduler::EventId event; |
| |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event)); |
| |
| eraseFace(faceId); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| Interest& request = face->sentInterests[1]; |
| |
| ndn::nfd::ControlParameters extractedParameters; |
| Name::Component verb; |
| extractParameters(request, verb, extractedParameters); |
| |
| BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters.getName(), identity); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(RebuildConnection, RemoteRegistratorFixture) |
| { |
| connectToHub(); |
| |
| Name identity("/remote/register"); |
| |
| insertEntryWithIdentity(identity); |
| |
| scheduler::EventId event; |
| |
| remoteRegistrator->m_regEntries.insert( |
| nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event)); |
| |
| disconnectToHub(); |
| |
| connectToHub(); |
| |
| BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2); |
| |
| Interest& request1 = face->sentInterests[0]; |
| Interest& request2 = face->sentInterests[1]; |
| |
| ndn::nfd::ControlParameters extractedParameters1, extractedParameters2; |
| Name::Component verb1, verb2; |
| extractParameters(request1, verb1, extractedParameters1); |
| extractParameters(request2, verb2, extractedParameters2); |
| |
| BOOST_CHECK_EQUAL(verb1, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(verb2, REGISTER_VERB); |
| BOOST_CHECK_EQUAL(extractedParameters1.getName(), |
| extractedParameters2.getName()); |
| } |
| |
| BOOST_AUTO_TEST_SUITE_END() |
| |
| } // namespace tests |
| } // namespace rib |
| } // namespace nfd |