diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index f9a2771..36e9e8a 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -1626,6 +1626,7 @@
   ControlParameters resultParameters;
   resultParameters.setUri("dummy://");
   resultParameters.setFaceId(FACEID_RESERVED_MAX + 1);
+  resultParameters.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
 
   shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
 
diff --git a/tests/daemon/mgmt/face-manager/create-face.t.cpp b/tests/daemon/mgmt/face-manager/create-face.t.cpp
new file mode 100644
index 0000000..3a70619
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager/create-face.t.cpp
@@ -0,0 +1,449 @@
+/* -*- 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 "mgmt/face-manager.hpp"
+#include "mgmt/internal-face.hpp"
+#include "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <boost/property_tree/info_parser.hpp>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, BaseFixture)
+
+BOOST_AUTO_TEST_SUITE(CreateFace)
+
+class FaceManagerNode
+{
+public:
+  FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
+    : face(make_shared<InternalFace>())
+    , manager(forwarder.getFaceTable(), face, keyChain)
+  {
+    std::string basicConfig =
+      "face_system\n"
+      "{\n"
+      "  tcp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "  udp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "}\n"
+      "authorizations\n"
+      "{\n"
+      "  authorize\n"
+      "  {\n"
+      "    certfile any\n"
+      "    privileges\n"
+      "    {\n"
+      "      faces\n"
+      "    }\n"
+      "  }\n"
+      "}\n"
+      "\n";
+    std::istringstream input(basicConfig);
+    nfd::ConfigSection configSection;
+    boost::property_tree::read_info(input, configSection);
+
+    ConfigFile config;
+    manager.setConfigFile(config);
+    face->getValidator().setConfigFile(config);
+    config.parse(configSection, false, "dummy-config");
+  }
+
+  void
+  closeFaces()
+  {
+    std::vector<shared_ptr<Face>> facesToClose;
+    std::copy(forwarder.getFaceTable().begin(), forwarder.getFaceTable().end(),
+              std::back_inserter(facesToClose));
+    for (auto face : facesToClose) {
+      face->close();
+    }
+  }
+
+public:
+  Forwarder forwarder;
+  shared_ptr<InternalFace> face;
+  FaceManager manager;
+};
+
+class FaceManagerFixture : public UnitTestTimeFixture
+{
+public:
+  FaceManagerFixture()
+    : node1(keyChain, "16363")
+    , node2(keyChain, "26363")
+  {
+  }
+
+  ~FaceManagerFixture()
+  {
+    node1.closeFaces();
+    node2.closeFaces();
+    advanceClocks(time::milliseconds(1), 100);
+  }
+
+public:
+  ndn::KeyChain keyChain;
+  FaceManagerNode node1; // used to test FaceManager
+  FaceManagerNode node2; // acts as a remote endpoint
+};
+
+class TcpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class TcpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class TcpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class UdpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class UdpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class UdpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class Success
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(200)
+      .setText("Success");
+  }
+};
+
+template<int CODE>
+class Failure
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(CODE)
+      .setText("Error"); // error description should not be checked
+  }
+};
+
+namespace mpl = boost::mpl;
+
+// pairs of CreateCommand and Success status
+typedef mpl::vector<mpl::pair<TcpFaceOnDemand, Failure<500>>,
+                    mpl::pair<TcpFacePersistent, Success>,
+                    mpl::pair<TcpFacePermanent, Failure<500>>,
+                    mpl::pair<UdpFaceOnDemand, Failure<500>>,
+                    mpl::pair<UdpFacePersistent, Success>,
+                    mpl::pair<UdpFacePermanent, Success>> Faces;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerFixture)
+{
+  typedef typename T::first FaceType;
+  typedef typename T::second CreateResult;
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(FaceType().getParameters().wireEncode());
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  this->keyChain.sign(*command);
+
+  bool hasCallbackFired = false;
+  this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+      if (!command->getName().isPrefixOf(response.getName())) {
+        return;
+      }
+
+      ControlResponse actual(response.getContent().blockFromValue());
+      ControlResponse expected(CreateResult().getExpected());
+      BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
+      BOOST_MESSAGE(actual.getText());
+
+      if (actual.getBody().hasWire()) {
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+
+        BOOST_CHECK_EQUAL(expectedParams.getUri(), actualParams.getUri());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+      }
+      hasCallbackFired = true;
+    });
+
+  this->node1.face->sendInterest(*command);
+  this->advanceClocks(time::milliseconds(1), 10);
+
+  BOOST_CHECK(hasCallbackFired);
+}
+
+
+typedef mpl::vector<// mpl::pair<mpl::pair<TcpFacePersistent, TcpFacePermanent>, TcpFacePermanent>, // no need to check now
+                    // mpl::pair<mpl::pair<TcpFacePermanent, TcpFacePersistent>, TcpFacePermanent>, // 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, FaceManagerFixture)
+{
+  typedef typename T::first::first FaceType1;
+  typedef typename T::first::second FaceType2;
+  typedef typename T::second FinalFaceType;
+
+  {
+    // create face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType1().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType2().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onReceiveData.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);
+
+        ControlParameters expectedParams(FinalFaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+
+// class TcpFace
+// {
+// public:
+//   ControlParameters
+//   getParameters()
+//   {
+//     return ControlParameters()
+//       .setUri("tcp4://127.0.0.1:16363")
+//       .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+//   }
+// };
+
+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, FaceManagerFixture)
+{
+  typedef typename T::first  OtherNodeFace;
+  typedef typename T::second FaceType;
+
+  {
+    // create on-demand face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(OtherNodeFace().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    ndn::util::signal::ScopedConnection connection =
+      this->node2.face->onReceiveData.connect([this, command] (const Data& response) {
+          if (!command->getName().isPrefixOf(response.getName())) {
+            return;
+          }
+
+          ControlResponse controlResponse(response.getContent().blockFromValue());
+          BOOST_REQUIRE_EQUAL(controlResponse.getText(), "Success");
+          BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 200);
+          uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
+          auto face = this->node2.forwarder.getFace(static_cast<FaceId>(faceId));
+
+          // to force creation of on-demand face
+          auto dummyInterest = make_shared<Interest>("/hello/world");
+          face->sendInterest(*dummyInterest);
+        });
+
+    this->node2.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  // make sure there is on-demand face
+  bool onDemandFaceFound = false;
+  FaceUri onDemandFaceUri(FaceType().getParameters().getUri());
+  for (auto face : this->node1.forwarder.getFaceTable()) {
+    if (face->getRemoteUri() == onDemandFaceUri) {
+      onDemandFaceFound = true;
+      break;
+    }
+  }
+  BOOST_REQUIRE(onDemandFaceFound);
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onReceiveData.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);
+
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // CreateFace
+
+BOOST_AUTO_TEST_SUITE_END() // MgmtFaceManager
+
+} // tests
+} // nfd
