mgmt: add faces/update command
refs #3731 Change-Id: I79777a10feecb2de83276371100cc86a43d0e76d
This commit is contained in:
1 parent
64567bb12a
commit
b5aa7f58e8
5 files changed
+686
-45
No files matched your search
@@ -59,6 +59,9 @@ FaceManager::FaceManager(FaceTable& faceTable, Dispatcher& dispatcher, CommandAu
|
||||
registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
|
||||
bind(&FaceManager::createFace, this, _2, _3, _4, _5));
|
||||
|
||||
registerCommandHandler<ndn::nfd::FaceUpdateCommand>("update",
|
||||
bind(&FaceManager::updateFace, this, _2, _3, _4, _5));
|
||||
|
||||
registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
|
||||
bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
|
||||
|
||||
@@ -143,6 +146,8 @@ FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
|
||||
|
||||
m_faceTable.add(newFace);
|
||||
|
||||
// TODO: #3731: Verify and add Flags
|
||||
|
||||
// Set ControlResponse parameters
|
||||
response.setFaceId(newFace->getId());
|
||||
response.setFacePersistency(newFace->getPersistency());
|
||||
@@ -160,6 +165,69 @@ FaceManager::afterCreateFaceFailure(uint32_t status,
|
||||
done(ControlResponse(status, reason));
|
||||
}
|
||||
|
||||
void
|
||||
FaceManager::updateFace(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done)
|
||||
{
|
||||
FaceId faceId = parameters.getFaceId();
|
||||
if (faceId == 0) {
|
||||
// Self-updating
|
||||
shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = interest.getTag<lp::IncomingFaceIdTag>();
|
||||
if (incomingFaceIdTag == nullptr) {
|
||||
NFD_LOG_TRACE("unable to determine face for self-update");
|
||||
done(ControlResponse(404, "No FaceId specified and IncomingFaceId not available"));
|
||||
return;
|
||||
}
|
||||
faceId = *incomingFaceIdTag;
|
||||
}
|
||||
|
||||
Face* face = m_faceTable.get(faceId);
|
||||
|
||||
if (face == nullptr) {
|
||||
NFD_LOG_TRACE("invalid face specified");
|
||||
done(ControlResponse(404, "Specified face does not exist"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify validity of requested changes
|
||||
ControlParameters response;
|
||||
bool areParamsValid = true;
|
||||
|
||||
if (parameters.hasFacePersistency()) {
|
||||
// TODO #3232: Add FacePersistency updating
|
||||
NFD_LOG_TRACE("received unsupported face persistency change");
|
||||
areParamsValid = false;
|
||||
response.setFacePersistency(parameters.getFacePersistency());
|
||||
}
|
||||
|
||||
if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
|
||||
parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
|
||||
face->getScope() != ndn::nfd::FACE_SCOPE_LOCAL) {
|
||||
NFD_LOG_TRACE("received request to enable local fields on non-local face");
|
||||
areParamsValid = false;
|
||||
response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED,
|
||||
parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
|
||||
}
|
||||
|
||||
if (!areParamsValid) {
|
||||
done(ControlResponse(409, "Invalid properties specified").setBody(response.wireEncode()));
|
||||
return;
|
||||
}
|
||||
|
||||
// All specified properties are valid, so make changes
|
||||
|
||||
// TODO #3232: Add FacePersistency updating
|
||||
|
||||
setLinkServiceOptions(*face, parameters, response);
|
||||
|
||||
// Set remaining ControlResponse fields
|
||||
response.setFaceId(faceId);
|
||||
response.setFacePersistency(face->getPersistency());
|
||||
|
||||
done(ControlResponse(200, "OK").setBody(response.wireEncode()));
|
||||
}
|
||||
|
||||
void
|
||||
FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
@@ -183,8 +251,7 @@ FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO#3226 redesign enable-local-control
|
||||
// For now, enable-local-control will enable all local fields in GenericLinkService.
|
||||
// enable-local-control will enable all local fields in GenericLinkService
|
||||
auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
|
||||
if (service == nullptr) {
|
||||
return done(ControlResponse(503, "LinkService type not supported"));
|
||||
@@ -208,8 +275,7 @@ FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO#3226 redesign disable-local-control
|
||||
// For now, disable-local-control will disable all local fields in GenericLinkService.
|
||||
// disable-local-control will disable all local fields in GenericLinkService
|
||||
auto service = dynamic_cast<face::GenericLinkService*>(face->getLinkService());
|
||||
if (service == nullptr) {
|
||||
return done(ControlResponse(503, "LinkService type not supported"));
|
||||
@@ -250,6 +316,25 @@ FaceManager::findFaceForLocalControl(const Interest& request,
|
||||
return face;
|
||||
}
|
||||
|
||||
void
|
||||
FaceManager::setLinkServiceOptions(Face& face,
|
||||
const ControlParameters& parameters,
|
||||
ControlParameters& response)
|
||||
{
|
||||
auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
|
||||
BOOST_ASSERT(linkService != nullptr);
|
||||
|
||||
auto options = linkService->getOptions();
|
||||
if (parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
|
||||
face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
|
||||
options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
|
||||
}
|
||||
linkService->setOptions(options);
|
||||
|
||||
// Set Flags for ControlResponse
|
||||
response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
|
||||
}
|
||||
|
||||
void
|
||||
FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
|
||||
ndn::mgmt::StatusDatasetContext& context)
|
||||
|
||||
@@ -60,16 +60,27 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE: // ControlCommand
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done);
|
||||
|
||||
void
|
||||
updateFace(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done);
|
||||
|
||||
void
|
||||
destroyFace(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done);
|
||||
|
||||
/**
|
||||
* \deprecated use Flags+Mask in faces/update instead
|
||||
*/
|
||||
void
|
||||
enableLocalControl(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done);
|
||||
|
||||
/**
|
||||
* \deprecated use Flags+Mask in faces/update instead
|
||||
*/
|
||||
void
|
||||
disableLocalControl(const Name& topPrefix, const Interest& interest,
|
||||
const ControlParameters& parameters,
|
||||
@@ -91,6 +102,11 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers for ControlCommand
|
||||
const ControlParameters& parameters,
|
||||
const ndn::mgmt::CommandContinuation& done);
|
||||
|
||||
static void
|
||||
setLinkServiceOptions(Face& face,
|
||||
const ControlParameters& parameters,
|
||||
ControlParameters& response);
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE: // StatusDataset
|
||||
void
|
||||
listFaces(const Name& topPrefix, const Interest& interest,
|
||||
@@ -151,9 +167,9 @@ private: // configuration
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
std::map<std::string /*protocol*/, shared_ptr<ProtocolFactory>> m_factories;
|
||||
FaceTable& m_faceTable;
|
||||
|
||||
private:
|
||||
FaceTable& m_faceTable;
|
||||
ndn::mgmt::PostNotification m_postNotification;
|
||||
signal::ScopedConnection m_faceAddConn;
|
||||
signal::ScopedConnection m_faceRemoveConn;
|
||||
|
||||
@@ -84,19 +84,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class UdpFaceConnectToSelf // face that will cause afterCreateFaceFailure to be invoked
|
||||
// fails because remote endpoint is prohibited
|
||||
{
|
||||
public:
|
||||
ControlParameters
|
||||
getParameters()
|
||||
{
|
||||
return ControlParameters()
|
||||
.setUri("udp4://0.0.0.0:16363"); // cannot connect to self
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class UdpFacePersistent
|
||||
{
|
||||
public:
|
||||
@@ -121,41 +108,28 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Success
|
||||
class UdpFaceConnectToSelf // face that will cause afterCreateFaceFailure to be invoked
|
||||
// fails because remote endpoint is prohibited
|
||||
{
|
||||
public:
|
||||
ControlResponse
|
||||
getExpected()
|
||||
ControlParameters
|
||||
getParameters()
|
||||
{
|
||||
return ControlResponse()
|
||||
.setCode(200)
|
||||
.setText("OK");
|
||||
}
|
||||
};
|
||||
|
||||
template<int CODE>
|
||||
class Failure
|
||||
{
|
||||
public:
|
||||
ControlResponse
|
||||
getExpected()
|
||||
{
|
||||
return ControlResponse()
|
||||
.setCode(CODE)
|
||||
.setText("Error"); // error description should not be checked
|
||||
return ControlParameters()
|
||||
.setUri("udp4://0.0.0.0:16363"); // cannot connect to self
|
||||
}
|
||||
};
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
// pairs of CreateCommand and Success/Failure status
|
||||
typedef mpl::vector<mpl::pair<TcpFaceOnDemand, Failure<406>>,
|
||||
mpl::pair<TcpFacePersistent, Success>,
|
||||
mpl::pair<TcpFacePermanent, Failure<406>>,
|
||||
mpl::pair<UdpFaceOnDemand, Failure<406>>,
|
||||
mpl::pair<UdpFacePersistent, Success>,
|
||||
mpl::pair<UdpFacePermanent, Success>,
|
||||
mpl::pair<UdpFaceConnectToSelf, Failure<406>>> Faces;
|
||||
typedef mpl::vector<mpl::pair<TcpFaceOnDemand, CommandFailure<406>>,
|
||||
mpl::pair<TcpFacePersistent, CommandSuccess>,
|
||||
mpl::pair<TcpFacePermanent, CommandFailure<406>>,
|
||||
mpl::pair<UdpFaceOnDemand, CommandFailure<406>>,
|
||||
mpl::pair<UdpFacePersistent, CommandSuccess>,
|
||||
mpl::pair<UdpFacePermanent, CommandSuccess>,
|
||||
mpl::pair<UdpFaceConnectToSelf, CommandFailure<406>>> Faces;
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerCommandFixture)
|
||||
{
|
||||
@@ -186,10 +160,28 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerCommandFixture)
|
||||
BOOST_CHECK(actualParams.hasFaceId());
|
||||
BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
|
||||
|
||||
if (actual.getCode() != 200) {
|
||||
if (actual.getCode() == 200) {
|
||||
if (expectedParams.hasFlags()) {
|
||||
// TODO: #3731 check if Flags match
|
||||
}
|
||||
else {
|
||||
// TODO: #3731 check if Flags at defaults
|
||||
}
|
||||
}
|
||||
else {
|
||||
BOOST_CHECK_EQUAL(expectedParams.getUri(), actualParams.getUri());
|
||||
}
|
||||
}
|
||||
|
||||
if (actual.getCode() != 200) {
|
||||
// ensure face not created
|
||||
FaceUri uri(FaceType().getParameters().getUri());
|
||||
auto& faceTable = this->node1.manager.m_faceTable;
|
||||
BOOST_CHECK(std::none_of(faceTable.begin(), faceTable.end(), [uri] (Face& face) {
|
||||
return face.getRemoteUri() == uri;
|
||||
}));
|
||||
}
|
||||
|
||||
hasCallbackFired = true;
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, 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 "face-manager-command-fixture.hpp"
|
||||
#include "nfd-manager-common-fixture.hpp"
|
||||
|
||||
namespace nfd {
|
||||
namespace tests {
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Mgmt)
|
||||
BOOST_AUTO_TEST_SUITE(TestFaceManager)
|
||||
|
||||
class FaceManagerUpdateFixture : public FaceManagerCommandFixture
|
||||
{
|
||||
public:
|
||||
FaceManagerUpdateFixture()
|
||||
: faceId(0)
|
||||
{
|
||||
}
|
||||
|
||||
~FaceManagerUpdateFixture()
|
||||
{
|
||||
destroyFace();
|
||||
}
|
||||
|
||||
void
|
||||
createFace(const std::string& uri = "tcp4://127.0.0.1:26363",
|
||||
ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
|
||||
bool enableLocalFields = false)
|
||||
{
|
||||
ControlParameters params;
|
||||
params.setUri(uri);
|
||||
params.setFacePersistency(persistency);
|
||||
params.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, enableLocalFields);
|
||||
|
||||
Name commandName("/localhost/nfd/faces/create");
|
||||
commandName.append(params.wireEncode());
|
||||
auto command = makeInterest(commandName);
|
||||
m_keyChain.sign(*command);
|
||||
|
||||
bool hasCallbackFired = false;
|
||||
signal::ScopedConnection connection = this->node1.face.onSendData.connect(
|
||||
[this, command, &hasCallbackFired] (const Data& response) {
|
||||
if (!command->getName().isPrefixOf(response.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ControlResponse create(response.getContent().blockFromValue());
|
||||
BOOST_REQUIRE_EQUAL(create.getCode(), 200);
|
||||
|
||||
if (create.getBody().hasWire()) {
|
||||
ControlParameters faceParams(create.getBody());
|
||||
BOOST_REQUIRE(faceParams.hasFaceId());
|
||||
this->faceId = faceParams.getFaceId();
|
||||
}
|
||||
else {
|
||||
BOOST_FAIL("Face creation failed");
|
||||
}
|
||||
|
||||
hasCallbackFired = true;
|
||||
});
|
||||
|
||||
this->node1.face.receive(*command);
|
||||
this->advanceClocks(time::milliseconds(1), 5);
|
||||
|
||||
BOOST_REQUIRE(hasCallbackFired);
|
||||
}
|
||||
|
||||
void
|
||||
updateFace(const ControlParameters& requestParams,
|
||||
bool isSelfUpdating,
|
||||
const function<void(const ControlResponse& resp)>& checkResp)
|
||||
{
|
||||
Name commandName("/localhost/nfd/faces/update");
|
||||
commandName.append(requestParams.wireEncode());
|
||||
auto command = makeInterest(commandName);
|
||||
if (isSelfUpdating) {
|
||||
// Attach IncomingFaceIdTag to interest
|
||||
command->setTag(make_shared<lp::IncomingFaceIdTag>(faceId));
|
||||
}
|
||||
m_keyChain.sign(*command);
|
||||
|
||||
bool hasCallbackFired = false;
|
||||
signal::ScopedConnection connection = this->node1.face.onSendData.connect(
|
||||
[this, command, &hasCallbackFired, &checkResp] (const Data& response) {
|
||||
if (!command->getName().isPrefixOf(response.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ControlResponse actual(response.getContent().blockFromValue());
|
||||
checkResp(actual);
|
||||
|
||||
hasCallbackFired = true;
|
||||
});
|
||||
|
||||
this->node1.face.receive(*command);
|
||||
this->advanceClocks(time::milliseconds(1), 5);
|
||||
|
||||
BOOST_CHECK(hasCallbackFired);
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
destroyFace()
|
||||
{
|
||||
if (faceId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ControlParameters params;
|
||||
params.setFaceId(faceId);
|
||||
|
||||
Name commandName("/localhost/nfd/faces/destroy");
|
||||
commandName.append(params.wireEncode());
|
||||
auto command = makeInterest(commandName);
|
||||
m_keyChain.sign(*command);
|
||||
|
||||
bool hasCallbackFired = false;
|
||||
signal::ScopedConnection connection = this->node1.face.onSendData.connect(
|
||||
[this, command, &hasCallbackFired] (const Data& response) {
|
||||
if (!command->getName().isPrefixOf(response.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ControlResponse destroy(response.getContent().blockFromValue());
|
||||
BOOST_CHECK_EQUAL(destroy.getCode(), 200);
|
||||
|
||||
faceId = 0;
|
||||
hasCallbackFired = true;
|
||||
});
|
||||
|
||||
this->node1.face.receive(*command);
|
||||
this->advanceClocks(time::milliseconds(1), 5);
|
||||
|
||||
BOOST_CHECK(hasCallbackFired);
|
||||
}
|
||||
|
||||
public:
|
||||
FaceId faceId;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(UpdateFace, FaceManagerUpdateFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FaceDoesNotExist)
|
||||
{
|
||||
ControlParameters requestParams;
|
||||
requestParams.setFaceId(65535);
|
||||
|
||||
updateFace(requestParams, false, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(404, "Specified face does not exist");
|
||||
BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
});
|
||||
}
|
||||
|
||||
// TODO #3232: Expected failure until FacePersistency updating implemented
|
||||
BOOST_AUTO_TEST_CASE(UpdatePersistency)
|
||||
{
|
||||
createFace();
|
||||
|
||||
ControlParameters requestParams;
|
||||
requestParams.setFaceId(faceId);
|
||||
requestParams.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
|
||||
|
||||
updateFace(requestParams, false, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(409, "Invalid fields specified");
|
||||
BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
|
||||
if (actual.getBody().hasWire()) {
|
||||
ControlParameters actualParams(actual.getBody());
|
||||
|
||||
BOOST_REQUIRE(actualParams.hasFacePersistency());
|
||||
BOOST_CHECK_EQUAL(actualParams.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
|
||||
}
|
||||
else {
|
||||
BOOST_ERROR("Response does not contain ControlParameters");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class TcpLocalFieldsEnable
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
getUri()
|
||||
{
|
||||
return "tcp4://127.0.0.1:26363";
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v4
|
||||
getIpAddress()
|
||||
{
|
||||
return boost::asio::ip::address_v4::from_string("127.0.0.1");
|
||||
}
|
||||
|
||||
ndn::nfd::FacePersistency
|
||||
getPersistency()
|
||||
{
|
||||
return ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
}
|
||||
|
||||
bool
|
||||
getInitLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabledMask()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldHaveWire()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class TcpLocalFieldsDisable
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
getUri()
|
||||
{
|
||||
return "tcp4://127.0.0.1:26363";
|
||||
}
|
||||
|
||||
ndn::nfd::FacePersistency
|
||||
getPersistency()
|
||||
{
|
||||
return ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
}
|
||||
|
||||
bool
|
||||
getInitLocalFieldsEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabledMask()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldHaveWire()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// UDP faces are non-local by definition
|
||||
class UdpLocalFieldsEnable
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
getUri()
|
||||
{
|
||||
return "udp4://127.0.0.1:26363";
|
||||
}
|
||||
|
||||
ndn::nfd::FacePersistency
|
||||
getPersistency()
|
||||
{
|
||||
return ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
}
|
||||
|
||||
bool
|
||||
getInitLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabledMask()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldHaveWire()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// UDP faces are non-local by definition
|
||||
// In this test case, attempt to disable local fields on face with local fields already disabled
|
||||
class UdpLocalFieldsDisable
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
getUri()
|
||||
{
|
||||
return "udp4://127.0.0.1:26363";
|
||||
}
|
||||
|
||||
ndn::nfd::FacePersistency
|
||||
getPersistency()
|
||||
{
|
||||
return ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
}
|
||||
|
||||
bool
|
||||
getInitLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabledMask()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldHaveWire()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// In this test case, set Flags to enable local fields on non-local face, but exclude local fields
|
||||
// from Mask. This test case will pass as no action is taken due to the missing Mask bit.
|
||||
class UdpLocalFieldsEnableNoMaskBit
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
getUri()
|
||||
{
|
||||
return "udp4://127.0.0.1:26363";
|
||||
}
|
||||
|
||||
ndn::nfd::FacePersistency
|
||||
getPersistency()
|
||||
{
|
||||
return ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
|
||||
}
|
||||
|
||||
bool
|
||||
getInitLocalFieldsEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
getLocalFieldsEnabledMask()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
shouldHaveWire()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
typedef mpl::vector<mpl::pair<TcpLocalFieldsEnable, CommandSuccess>,
|
||||
mpl::pair<TcpLocalFieldsDisable, CommandSuccess>,
|
||||
mpl::pair<UdpLocalFieldsEnable, CommandFailure<409>>,
|
||||
mpl::pair<UdpLocalFieldsDisable, CommandSuccess>,
|
||||
mpl::pair<UdpLocalFieldsEnableNoMaskBit, CommandSuccess>> LocalFieldFaces;
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(UpdateLocalFields, T, LocalFieldFaces)
|
||||
{
|
||||
typedef typename T::first TestType;
|
||||
typedef typename T::second ResultType;
|
||||
|
||||
createFace(TestType().getUri(), TestType().getPersistency(), TestType().getInitLocalFieldsEnabled());
|
||||
|
||||
ControlParameters requestParams;
|
||||
requestParams.setFaceId(faceId);
|
||||
requestParams.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, TestType().getLocalFieldsEnabled());
|
||||
if (!TestType().getLocalFieldsEnabledMask()) {
|
||||
requestParams.unsetFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
|
||||
}
|
||||
|
||||
updateFace(requestParams, false, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(ResultType().getExpected().getCode(), "");
|
||||
BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
|
||||
if (TestType().shouldHaveWire() && actual.getBody().hasWire()) {
|
||||
ControlParameters actualParams(actual.getBody());
|
||||
|
||||
BOOST_CHECK(!actualParams.hasFacePersistency());
|
||||
BOOST_CHECK(actualParams.hasFlags());
|
||||
BOOST_CHECK(actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
|
||||
BOOST_CHECK(actualParams.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UpdateLocalFieldsEnableDisable)
|
||||
{
|
||||
createFace();
|
||||
|
||||
ControlParameters enableParams;
|
||||
enableParams.setFaceId(faceId);
|
||||
enableParams.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true);
|
||||
|
||||
ControlParameters disableParams;
|
||||
disableParams.setFaceId(faceId);
|
||||
disableParams.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, false);
|
||||
|
||||
updateFace(enableParams, false, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(200, "OK");
|
||||
BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
|
||||
if (actual.getBody().hasWire()) {
|
||||
ControlParameters actualParams(actual.getBody());
|
||||
|
||||
BOOST_CHECK(actualParams.hasFaceId());
|
||||
BOOST_CHECK(actualParams.hasFacePersistency());
|
||||
BOOST_REQUIRE(actualParams.hasFlags());
|
||||
// Check if flags indicate local fields enabled
|
||||
BOOST_CHECK(actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
|
||||
}
|
||||
else {
|
||||
BOOST_ERROR("Enable: Response does not contain ControlParameters");
|
||||
}
|
||||
});
|
||||
|
||||
updateFace(disableParams, false, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(200, "OK");
|
||||
BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
|
||||
if (actual.getBody().hasWire()) {
|
||||
ControlParameters actualParams(actual.getBody());
|
||||
|
||||
BOOST_CHECK(actualParams.hasFaceId());
|
||||
BOOST_CHECK(actualParams.hasFacePersistency());
|
||||
BOOST_REQUIRE(actualParams.hasFlags());
|
||||
// Check if flags indicate local fields disabled
|
||||
BOOST_CHECK(!actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
|
||||
}
|
||||
else {
|
||||
BOOST_ERROR("Disable: Response does not contain ControlParameters");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SelfUpdating)
|
||||
{
|
||||
createFace();
|
||||
|
||||
// Send a command that does nothing (will return 200) and does not contain a FaceId
|
||||
ControlParameters sentParams;
|
||||
|
||||
updateFace(sentParams, true, [] (const ControlResponse& actual) {
|
||||
ControlResponse expected(200, "OK");
|
||||
BOOST_REQUIRE_EQUAL(actual.getCode(), expected.getCode());
|
||||
BOOST_TEST_MESSAGE(actual.getText());
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // UpdateFace
|
||||
BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
|
||||
BOOST_AUTO_TEST_SUITE_END() // Mgmt
|
||||
|
||||
} // namespace tests
|
||||
} // namespace nfd
|
||||
@@ -55,6 +55,31 @@ protected:
|
||||
shared_ptr<CommandAuthenticator> m_authenticator;
|
||||
};
|
||||
|
||||
class CommandSuccess
|
||||
{
|
||||
public:
|
||||
ControlResponse
|
||||
getExpected()
|
||||
{
|
||||
return ControlResponse()
|
||||
.setCode(200)
|
||||
.setText("OK");
|
||||
}
|
||||
};
|
||||
|
||||
template<int CODE>
|
||||
class CommandFailure
|
||||
{
|
||||
public:
|
||||
ControlResponse
|
||||
getExpected()
|
||||
{
|
||||
return ControlResponse()
|
||||
.setCode(CODE);
|
||||
// error description should not be checked
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tests
|
||||
} // namespace nfd
|
||||
|
||||
|
||||
Reference in new issue
Block a user