management: Controller validates ControlCommand response

refs #3653

Change-Id: I70fd96075357840928bc813e64030b3e513f698a
diff --git a/src/management/nfd-controller.cpp b/src/management/nfd-controller.cpp
index 5fc755d..72299f0 100644
--- a/src/management/nfd-controller.cpp
+++ b/src/management/nfd-controller.cpp
@@ -72,8 +72,22 @@
                                    const CommandSucceedCallback& onSuccess,
                                    const CommandFailCallback& onFailure)
 {
-  /// \todo verify Data signature
+  m_validator.validate(data,
+    [=] (const shared_ptr<const Data>& data) {
+      this->processValidatedCommandResponse(*data, command, onSuccess, onFailure);
+    },
+    [=] (const shared_ptr<const Data>&, const std::string& msg) {
+      onFailure(ERROR_VALIDATION, msg);
+    }
+  );
+}
 
+void
+Controller::processValidatedCommandResponse(const Data& data,
+                                            const shared_ptr<ControlCommand>& command,
+                                            const CommandSucceedCallback& onSuccess,
+                                            const CommandFailCallback& onFailure)
+{
   ControlResponse response;
   try {
     response.wireDecode(data.getContent().blockFromValue());
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
index 9fa721b..f1d6df9 100644
--- a/src/management/nfd-controller.hpp
+++ b/src/management/nfd-controller.hpp
@@ -107,6 +107,12 @@
                          const CommandSucceedCallback& onSuccess,
                          const CommandFailCallback& onFailure);
 
+  void
+  processValidatedCommandResponse(const Data& data,
+                                  const shared_ptr<ControlCommand>& command,
+                                  const CommandSucceedCallback& onSuccess,
+                                  const CommandFailCallback& onFailure);
+
   template<typename Dataset>
   void
   fetchDataset(shared_ptr<Dataset> dataset,
@@ -130,7 +136,6 @@
   void
   processDatasetFetchError(const CommandFailCallback& onFailure, uint32_t code, std::string msg);
 
-
 public:
   /** \brief error code for timeout
    */
diff --git a/tests/unit-tests/management/nfd-controller.t.cpp b/tests/unit-tests/management/nfd-controller.t.cpp
index bc9aa1a..8a944f8 100644
--- a/tests/unit-tests/management/nfd-controller.t.cpp
+++ b/tests/unit-tests/management/nfd-controller.t.cpp
@@ -161,6 +161,37 @@
                     ControlCommand::ArgumentError);
 }
 
+BOOST_AUTO_TEST_CASE(ValidationFailure)
+{
+  this->setValidationResult(false);
+
+  ControlParameters parameters;
+  parameters.setUri("tcp4://192.0.2.1:6363");
+
+  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
+                         parameters, succeedCallback, failCallback));
+  this->advanceClocks(time::milliseconds(1));
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  const Interest& requestInterest = face.sentInterests[0];
+
+  ControlParameters responseBody;
+  responseBody.setUri("tcp4://192.0.2.1:6363")
+              .setFaceId(22)
+              .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
+  ControlResponse responsePayload(201, "created");
+  responsePayload.setBody(responseBody.wireEncode());
+
+  auto responseData = makeData(requestInterest.getName());
+  responseData->setContent(responsePayload.wireEncode());
+  face.receive(*responseData);
+  this->advanceClocks(time::milliseconds(1));
+
+  BOOST_CHECK_EQUAL(succeeds.size(), 0);
+  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
+  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_VALIDATION);
+}
+
 BOOST_AUTO_TEST_CASE(ErrorCode)
 {
   ControlParameters parameters;