mgmt+tools: rework FacePersistency handling in faces/create and faces/update

1. enable changing persistency in faces/update command
2. reject faces/create request if the face already exists
3. nfdc changes to support the above

Change-Id: I659906da846608a42a768f08fb110ceee1a947a7
refs: #3232
diff --git a/tests/daemon/mgmt/face-manager-create-face.t.cpp b/tests/daemon/mgmt/face-manager-create-face.t.cpp
index ed89388..5cfe952 100644
--- a/tests/daemon/mgmt/face-manager-create-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -23,6 +23,7 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "mgmt/face-manager.hpp"
 #include "face-manager-command-fixture.hpp"
 #include "nfd-manager-common-fixture.hpp"
 
@@ -206,8 +207,8 @@
 
     ControlResponse actual(response.getContent().blockFromValue());
     ControlResponse expected(CreateResult().getExpected());
-    BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
     BOOST_TEST_MESSAGE(actual.getText());
+    BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
 
     if (actual.getBody().hasWire()) {
       ControlParameters expectedParams(FaceType().getParameters());
@@ -249,25 +250,16 @@
   BOOST_CHECK(hasCallbackFired);
 }
 
-
-typedef mpl::vector<// mpl::pair<mpl::pair<TcpFacePersistent, TcpFacePermanent>, TcpFacePermanent>, // no need to check now
-                    // mpl::pair<mpl::pair<TcpFacePermanent, TcpFacePersistent>, TcpFacePersistent>, // no need to check now
-                    mpl::pair<mpl::pair<UdpFacePersistent, UdpFacePermanent>, UdpFacePermanent>,
-                    mpl::pair<mpl::pair<UdpFacePermanent, UdpFacePersistent>, UdpFacePermanent>> FaceTransitions;
-
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFace, T, FaceTransitions, FaceManagerCommandFixture)
+BOOST_FIXTURE_TEST_CASE(ExistingFace, FaceManagerCommandFixture)
 {
-  typedef typename T::first::first FaceType1;
-  typedef typename T::first::second FaceType2;
-  typedef typename T::second FinalFaceType;
+  using FaceType = UdpFacePersistent;
 
   {
     // create face
 
     Name commandName("/localhost/nfd/faces");
     commandName.append("create");
-    commandName.append(FaceType1().getParameters().wireEncode());
+    commandName.append(FaceType().getParameters().wireEncode());
     auto command = makeInterest(commandName);
     m_keyChain.sign(*command);
 
@@ -275,116 +267,12 @@
     this->advanceClocks(time::milliseconds(1), 5);
   }
 
-  //
-  {
-    // re-create face (= change face persistency)
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(FaceType2().getParameters().wireEncode());
-    auto command = makeInterest(commandName);
-    m_keyChain.sign(*command);
-
-    bool hasCallbackFired = false;
-    this->node1.face.onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
-        if (!command->getName().isPrefixOf(response.getName())) {
-          return;
-        }
-
-        ControlResponse actual(response.getContent().blockFromValue());
-        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
-        BOOST_TEST_MESSAGE(actual.getText());
-
-        ControlParameters expectedParams(FinalFaceType().getParameters());
-        ControlParameters actualParams(actual.getBody());
-        BOOST_REQUIRE(!actualParams.hasUri()); // Uri parameter is only included on command failure
-        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
-
-        hasCallbackFired = true;
-      });
-
-    this->node1.face.receive(*command);
-    this->advanceClocks(time::milliseconds(1), 5);
-
-    BOOST_CHECK(hasCallbackFired);
-  }
-}
-
-
-class UdpFace
-{
-public:
-  ControlParameters
-  getParameters()
-  {
-    return ControlParameters()
-      .setUri("udp4://127.0.0.1:16363")
-      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-  }
-};
-
-
-// Note that the transitions from on-demand TcpFace are intentionally not tested.
-// On-demand TcpFace has a remote endpoint with a randomized port number.  Normal face
-// creation operations will not need to create a face toward a remote port not listened by
-// a channel.
-
-typedef mpl::vector<mpl::pair<UdpFace, UdpFacePersistent>,
-                    mpl::pair<UdpFace, UdpFacePermanent>> OnDemandFaceTransitions;
-
-// need a slightly different logic to test transitions from OnDemand state
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFaceOnDemand, T, OnDemandFaceTransitions, FaceManagerCommandFixture)
-{
-  typedef typename T::first  OtherNodeFace;
-  typedef typename T::second FaceType;
+  // find the created face
+  auto foundFace = this->node1.findFaceByUri(FaceType().getParameters().getUri());
+  BOOST_REQUIRE(foundFace != nullptr);
 
   {
-    // create on-demand face
-
-    Name commandName("/localhost/nfd/faces");
-    commandName.append("create");
-    commandName.append(OtherNodeFace().getParameters().wireEncode());
-    auto command = makeInterest(commandName);
-    m_keyChain.sign(*command);
-
-    ndn::util::signal::ScopedConnection connection =
-      this->node2.face.onSendData.connect([this, command] (const Data& response) {
-        if (!command->getName().isPrefixOf(response.getName())) {
-          return;
-        }
-
-        ControlResponse controlResponse(response.getContent().blockFromValue());
-        BOOST_REQUIRE_EQUAL(controlResponse.getText(), "OK");
-        BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 200);
-        BOOST_REQUIRE(!ControlParameters(controlResponse.getBody()).hasUri());
-        uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
-        auto face = this->node2.faceTable.get(static_cast<FaceId>(faceId));
-
-        // to force creation of on-demand face
-        auto dummyInterest = make_shared<Interest>("/hello/world");
-        face->sendInterest(*dummyInterest);
-      });
-
-    this->node2.face.receive(*command);
-    this->advanceClocks(time::milliseconds(1), 5); // let node2 process command and send Interest
-    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // allow wallclock time for socket IO
-    this->advanceClocks(time::milliseconds(1), 5); // let node1 accept Interest and create on-demand face
-  }
-
-  // make sure there is on-demand face
-  FaceUri onDemandFaceUri(FaceType().getParameters().getUri());
-  const Face* foundFace = nullptr;
-  for (const Face& face : this->node1.faceTable) {
-    if (face.getRemoteUri() == onDemandFaceUri) {
-      foundFace = &face;
-      break;
-    }
-  }
-  BOOST_REQUIRE_MESSAGE(foundFace != nullptr, "on-demand face is not created");
-
-  //
-  {
-    // re-create face (= change face persistency)
+    // re-create face
 
     Name commandName("/localhost/nfd/faces");
     commandName.append("create");
@@ -400,14 +288,12 @@
         }
 
         ControlResponse actual(response.getContent().blockFromValue());
-        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
+        BOOST_REQUIRE_EQUAL(actual.getCode(), 409);
 
-        ControlParameters expectedParams(FaceType().getParameters());
         ControlParameters actualParams(actual.getBody());
-        BOOST_REQUIRE(!actualParams.hasUri());
-        BOOST_CHECK_EQUAL(actualParams.getFacePersistency(), expectedParams.getFacePersistency());
-        BOOST_CHECK_EQUAL(actualParams.getFaceId(), foundFace->getId());
-        BOOST_CHECK_EQUAL(foundFace->getPersistency(), expectedParams.getFacePersistency());
+        BOOST_CHECK_EQUAL(foundFace->getId(), actualParams.getFaceId());
+        BOOST_CHECK_EQUAL(foundFace->getRemoteUri().toString(), actualParams.getUri());
+        BOOST_CHECK_EQUAL(foundFace->getPersistency(), actualParams.getFacePersistency());
 
         hasCallbackFired = true;
       });