mgmt: declare cs/erase command
refs #4318
Change-Id: If34ba8d55a4d46d53f552f4edd748623d4c0e55e
diff --git a/src/mgmt/nfd/control-command.cpp b/src/mgmt/nfd/control-command.cpp
index 9f978f0..556a0ed 100644
--- a/src/mgmt/nfd/control-command.cpp
+++ b/src/mgmt/nfd/control-command.cpp
@@ -270,6 +270,38 @@
.required(CONTROL_PARAMETER_FLAGS);
}
+CsEraseCommand::CsEraseCommand()
+ : ControlCommand("cs", "erase")
+{
+ m_requestValidator
+ .required(CONTROL_PARAMETER_NAME)
+ .optional(CONTROL_PARAMETER_N_CS_ENTRIES);
+ m_responseValidator
+ .required(CONTROL_PARAMETER_NAME)
+ .optional(CONTROL_PARAMETER_CAPACITY)
+ .required(CONTROL_PARAMETER_N_CS_ENTRIES);
+}
+
+void
+CsEraseCommand::validateRequest(const ControlParameters& parameters) const
+{
+ this->ControlCommand::validateRequest(parameters);
+
+ if (parameters.hasNCsEntries() && parameters.getNCsEntries() == 0) {
+ BOOST_THROW_EXCEPTION(ArgumentError("NCsEntries must be positive"));
+ }
+}
+
+void
+CsEraseCommand::validateResponse(const ControlParameters& parameters) const
+{
+ this->ControlCommand::validateResponse(parameters);
+
+ if (parameters.hasCapacity() && parameters.getCapacity() == 0) {
+ BOOST_THROW_EXCEPTION(ArgumentError("Capacity must be positive"));
+ }
+}
+
StrategyChoiceSetCommand::StrategyChoiceSetCommand()
: ControlCommand("strategy-choice", "set")
{
diff --git a/src/mgmt/nfd/control-command.hpp b/src/mgmt/nfd/control-command.hpp
index 74f0bb1..90d7d38 100644
--- a/src/mgmt/nfd/control-command.hpp
+++ b/src/mgmt/nfd/control-command.hpp
@@ -155,7 +155,7 @@
/**
* \ingroup management
* \brief represents a faces/update command
- * \sa https://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Update-a-face
+ * \sa https://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Update-the-static-properties-of-a-face
*/
class FaceUpdateCommand : public ControlCommand
{
@@ -231,7 +231,7 @@
/**
* \ingroup management
* \brief represents a cs/config command
- * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
+ * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-configuration
*/
class CsConfigCommand : public ControlCommand
{
@@ -242,6 +242,24 @@
/**
* \ingroup management
+ * \brief represents a cs/erase command
+ * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Erase-entries
+ */
+class CsEraseCommand : public ControlCommand
+{
+public:
+ CsEraseCommand();
+
+ void
+ validateRequest(const ControlParameters& parameters) const override;
+
+ void
+ validateResponse(const ControlParameters& parameters) const override;
+};
+
+
+/**
+ * \ingroup management
* \brief represents a strategy-choice/set command
* \sa https://redmine.named-data.net/projects/nfd/wiki/StrategyChoice#Set-the-strategy-for-a-namespace
*/
diff --git a/src/mgmt/nfd/control-parameters.cpp b/src/mgmt/nfd/control-parameters.cpp
index 1e4d9fe..c0377c5 100644
--- a/src/mgmt/nfd/control-parameters.cpp
+++ b/src/mgmt/nfd/control-parameters.cpp
@@ -76,6 +76,9 @@
if (this->hasFlags()) {
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
}
+ if (this->hasNCsEntries()) {
+ totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NCsEntries, m_nCsEntries);
+ }
if (this->hasCapacity()) {
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Capacity, m_capacity);
}
@@ -173,6 +176,12 @@
m_capacity = readNonNegativeInteger(*val);
}
+ val = m_wire.find(tlv::nfd::NCsEntries);
+ m_hasFields[CONTROL_PARAMETER_N_CS_ENTRIES] = val != m_wire.elements_end();
+ if (this->hasNCsEntries()) {
+ m_nCsEntries = readNonNegativeInteger(*val);
+ }
+
val = m_wire.find(tlv::nfd::Flags);
m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
if (this->hasFlags()) {
@@ -328,6 +337,10 @@
os << "Capacity: " << parameters.getCapacity() << ", ";
}
+ if (parameters.hasNCsEntries()) {
+ os << "NCsEntries: " << parameters.getNCsEntries() << ", ";
+ }
+
if (parameters.hasFlags()) {
os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
}
diff --git a/src/mgmt/nfd/control-parameters.hpp b/src/mgmt/nfd/control-parameters.hpp
index ca1d75d..7005e9d 100644
--- a/src/mgmt/nfd/control-parameters.hpp
+++ b/src/mgmt/nfd/control-parameters.hpp
@@ -41,6 +41,7 @@
CONTROL_PARAMETER_ORIGIN,
CONTROL_PARAMETER_COST,
CONTROL_PARAMETER_CAPACITY,
+ CONTROL_PARAMETER_N_CS_ENTRIES,
CONTROL_PARAMETER_FLAGS,
CONTROL_PARAMETER_MASK,
CONTROL_PARAMETER_STRATEGY,
@@ -59,6 +60,7 @@
"Origin",
"Cost",
"Capacity",
+ "NCsEntries",
"Flags",
"Mask",
"Strategy",
@@ -314,6 +316,36 @@
}
bool
+ hasNCsEntries() const
+ {
+ return m_hasFields[CONTROL_PARAMETER_N_CS_ENTRIES];
+ }
+
+ uint64_t
+ getNCsEntries() const
+ {
+ BOOST_ASSERT(this->hasNCsEntries());
+ return m_nCsEntries;
+ }
+
+ ControlParameters&
+ setNCsEntries(uint64_t nCsEntries)
+ {
+ m_wire.reset();
+ m_nCsEntries = nCsEntries;
+ m_hasFields[CONTROL_PARAMETER_N_CS_ENTRIES] = true;
+ return *this;
+ }
+
+ ControlParameters&
+ unsetNCsEntries()
+ {
+ m_wire.reset();
+ m_hasFields[CONTROL_PARAMETER_N_CS_ENTRIES] = false;
+ return *this;
+ }
+
+ bool
hasFlags() const
{
return m_hasFields[CONTROL_PARAMETER_FLAGS];
@@ -575,6 +607,7 @@
RouteOrigin m_origin;
uint64_t m_cost;
uint64_t m_capacity;
+ uint64_t m_nCsEntries;
uint64_t m_flags;
uint64_t m_mask;
Name m_strategy;
diff --git a/tests/unit-tests/mgmt/nfd/control-command.t.cpp b/tests/unit-tests/mgmt/nfd/control-command.t.cpp
index 0cc3642..d76b67c 100644
--- a/tests/unit-tests/mgmt/nfd/control-command.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/control-command.t.cpp
@@ -299,6 +299,69 @@
command.validateResponse(p3);
}
+BOOST_AUTO_TEST_CASE(CsEraseRequest)
+{
+ CsEraseCommand command;
+
+ // good no-limit request
+ ControlParameters p1;
+ p1.setName("/u4LYPNU8Q");
+ command.validateRequest(p1);
+ BOOST_CHECK(Name("/PREFIX/cs/erase").isPrefixOf(command.getRequestName("/PREFIX", p1)));
+
+ // good limit-entries request
+ ControlParameters p2;
+ p2.setName("/IMw1RaLF");
+ p2.setNCsEntries(177);
+ command.validateRequest(p2);
+
+ // bad request: zero entry
+ ControlParameters p3;
+ p3.setName("/ahMID1jcib");
+ p3.setNCsEntries(0);
+ BOOST_CHECK_THROW(command.validateRequest(p3), ControlCommand::ArgumentError);
+
+ // bad request: forbidden field
+ ControlParameters p4(p2);
+ p4.setCapacity(278);
+ BOOST_CHECK_THROW(command.validateRequest(p3), ControlCommand::ArgumentError);
+}
+
+BOOST_AUTO_TEST_CASE(CsEraseResponse)
+{
+ CsEraseCommand command;
+
+ // good normal response
+ ControlParameters p1;
+ p1.setName("/TwiIwCdR");
+ p1.setNCsEntries(1);
+ command.validateResponse(p1);
+
+ // good limit exceeded request
+ ControlParameters p2;
+ p2.setName("/NMsiy44pr");
+ p2.setCapacity(360);
+ p2.setNCsEntries(360);
+ command.validateResponse(p2);
+
+ // good zero-entry response
+ ControlParameters p3;
+ p3.setName("/5f1LRPh1L");
+ p3.setNCsEntries(0);
+ command.validateResponse(p3);
+
+ // bad request: missing NCsEntries
+ ControlParameters p4(p1);
+ p4.unsetNCsEntries();
+ BOOST_CHECK_THROW(command.validateResponse(p4), ControlCommand::ArgumentError);
+
+ // bad request: zero capacity
+ ControlParameters p5(p1);
+ p5.setCapacity(0);
+ BOOST_CHECK_THROW(command.validateResponse(p5), ControlCommand::ArgumentError);
+
+}
+
BOOST_AUTO_TEST_CASE(StrategyChoiceSet)
{
StrategyChoiceSetCommand command;
diff --git a/tests/unit-tests/mgmt/nfd/control-parameters.t.cpp b/tests/unit-tests/mgmt/nfd/control-parameters.t.cpp
index 80e8134..14be320 100644
--- a/tests/unit-tests/mgmt/nfd/control-parameters.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/control-parameters.t.cpp
@@ -43,6 +43,7 @@
BOOST_CHECK_EQUAL(decoded.hasOrigin(), false);
BOOST_CHECK_EQUAL(decoded.hasCost(), false);
BOOST_CHECK_EQUAL(decoded.hasCapacity(), false);
+ BOOST_CHECK_EQUAL(decoded.hasNCsEntries(), false);
BOOST_CHECK_EQUAL(decoded.hasFlags(), false);
BOOST_CHECK_EQUAL(decoded.hasMask(), false);
BOOST_CHECK_EQUAL(decoded.hasStrategy(), false);
@@ -56,6 +57,7 @@
input.setOrigin(ROUTE_ORIGIN_NLSR);
input.setCost(1388);
input.setCapacity(2632);
+ input.setNCsEntries(3100);
input.setFlags(0xAFC4);
input.setMask(0xF7A1);
input.setStrategy("/strategy-name");
@@ -70,6 +72,7 @@
BOOST_CHECK_EQUAL(decoded.hasOrigin(), true);
BOOST_CHECK_EQUAL(decoded.hasCost(), true);
BOOST_CHECK_EQUAL(decoded.hasCapacity(), true);
+ BOOST_CHECK_EQUAL(decoded.hasNCsEntries(), true);
BOOST_CHECK_EQUAL(decoded.hasFlags(), true);
BOOST_CHECK_EQUAL(decoded.hasMask(), true);
BOOST_CHECK_EQUAL(decoded.hasStrategy(), true);
@@ -83,6 +86,7 @@
BOOST_CHECK_EQUAL(decoded.getOrigin(), ROUTE_ORIGIN_NLSR);
BOOST_CHECK_EQUAL(decoded.getCost(), 1388);
BOOST_CHECK_EQUAL(decoded.getCapacity(), 2632);
+ BOOST_CHECK_EQUAL(decoded.getNCsEntries(), 3100);
BOOST_CHECK_EQUAL(decoded.getFlags(), 0xAFC4);
BOOST_CHECK_EQUAL(decoded.getMask(), 0xF7A1);
BOOST_CHECK_EQUAL(decoded.getStrategy(), "/strategy-name");
@@ -96,6 +100,7 @@
input.unsetOrigin();
input.unsetCost();
input.unsetCapacity();
+ input.unsetNCsEntries();
input.unsetFlags();
input.unsetMask();
input.unsetStrategy();
@@ -108,6 +113,7 @@
BOOST_CHECK_EQUAL(input.hasOrigin(), false);
BOOST_CHECK_EQUAL(input.hasCost(), false);
BOOST_CHECK_EQUAL(input.hasCapacity(), false);
+ BOOST_CHECK_EQUAL(input.hasNCsEntries(), false);
BOOST_CHECK_EQUAL(input.hasFlags(), false);
BOOST_CHECK_EQUAL(input.hasMask(), false);
BOOST_CHECK_EQUAL(input.hasStrategy(), false);