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..ffee5aa
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -0,0 +1,461 @@
+/* -*- 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 "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <ndn-cxx/mgmt/dispatcher.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include <boost/property_tree/info_parser.hpp>
+
+namespace nfd {
+namespace tests {
+
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_FIXTURE_TEST_SUITE(CreateFace, BaseFixture)
+
+class FaceManagerNode
+{
+public:
+  FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
+    : face(ndn::util::makeDummyClientFace(getGlobalIoService(), {true, true}))
+    , dispatcher(*face, keyChain, ndn::security::SigningInfo())
+    , manager(forwarder.getFaceTable(), dispatcher, validator)
+  {
+    dispatcher.addTopPrefix("/localhost/nfd");
+
+    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);
+    validator.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<ndn::util::DummyClientFace> face;
+  ndn::mgmt::Dispatcher dispatcher;
+  CommandValidator validator;
+  FaceManager manager;
+};
+
+class FaceManagerFixture : public UnitTestTimeFixture
+{
+public:
+  FaceManagerFixture()
+    : node1(keyChain, "16363")
+    , node2(keyChain, "26363")
+  {
+    advanceClocks(time::milliseconds(1), 100);
+  }
+
+  ~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 UdpFaceCannotConnect // face that will cause afterCreateFaceFailure to be invoked
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://0.0.0.0:16363"); // cannot connect to self
+  }
+};
+
+
+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("OK");
+  }
+};
+
+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>,
+                    mpl::pair<UdpFaceCannotConnect, Failure<408>>> 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->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
+      // std::cout << response << std::endl;
+      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->receive(*command);
+  this->advanceClocks(time::milliseconds(1), 100);
+
+  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->receive(*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->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);
+
+        ControlParameters expectedParams(FinalFaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    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, 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->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);
+          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->receive(*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->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);
+
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // CreateFace
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // tests
+} // nfd
diff --git a/tests/daemon/mgmt/face-manager-process-config.t.cpp b/tests/daemon/mgmt/face-manager-process-config.t.cpp
new file mode 100644
index 0000000..9463ac4
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager-process-config.t.cpp
@@ -0,0 +1,438 @@
+/* -*- 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 "face/udp-factory.hpp"
+
+#ifdef HAVE_LIBPCAP
+#include "face/ethernet-factory.hpp"
+#endif // HAVE_LIBPCAP
+
+#include "manager-common-fixture.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+class FaceManagerProcessConfigFixture : public ManagerCommonFixture
+{
+public:
+  FaceManagerProcessConfigFixture()
+    : m_manager(m_forwarder.getFaceTable(), m_dispatcher, m_validator)
+  {
+    m_manager.setConfigFile(m_config);
+  }
+
+public:
+  void
+  parseConfig(const std::string& type, bool isDryRun)
+  {
+    m_config.parse(type, isDryRun, "test-config");
+  }
+
+protected:
+  FaceManager m_manager;
+  ConfigFile m_config;
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceManagerProcessConfigFixture)
+
+#ifdef HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnix)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    path /tmp/nfd.sock\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnixUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+#endif // HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 16363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadIdleTimeout)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    idle_timeout hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroupV6)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group ::1\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpConflictingMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("udp") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<UdpFactory>(m_manager.m_factories.find("udp")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no UDP multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#ifdef HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEther)
+{
+
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group 01:00:5E:00:17:AA\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("ether") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<EthernetFactory>(m_manager.m_factories.find("ether")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no Ethernet multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#endif // HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
new file mode 100644
index 0000000..db24029
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager.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 "manager-common-fixture.hpp"
+#include "../face/dummy-face.hpp"
+#include "face/tcp-factory.hpp"
+#include "face/udp-factory.hpp"
+
+#include <ndn-cxx/util/random.hpp>
+#include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/management/nfd-channel-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
+
+namespace nfd {
+namespace tests {
+
+class FaceManagerFixture : public ManagerCommonFixture
+{
+public:
+  FaceManagerFixture()
+    : m_faceTable(m_forwarder.getFaceTable())
+    , m_manager(m_faceTable, m_dispatcher, m_validator)
+  {
+    setTopPrefixAndPrivilege("/localhost/nfd", "faces");
+  }
+
+public:
+  template<typename Face>
+  shared_ptr<Face>
+  addFace(bool wantRemoveLastNotification = false)
+  {
+    auto face = make_shared<Face>();
+    m_faceTable.add(face);
+    advanceClocks(time::milliseconds(1), 10); // wait for notification posted
+    if (wantRemoveLastNotification) {
+      m_responses.pop_back();
+    }
+    return face;
+  }
+
+protected:
+  FaceTable& m_faceTable;
+  FaceManager m_manager;
+};
+
+BOOST_FIXTURE_TEST_SUITE(Mgmt, FaceManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_AUTO_TEST_SUITE(DestroyFace)
+
+BOOST_AUTO_TEST_CASE(Existing)
+{
+  auto addedFace = addFace<DummyFace>(true); // clear notification for creation
+
+  auto parameters = ControlParameters().setFaceId(addedFace->getId());
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2); // one response and one notification
+  // notification is already tested, so ignore it
+
+  BOOST_CHECK_EQUAL(checkResponse(1, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+
+  BOOST_CHECK_EQUAL(addedFace->getId(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(NonExisting)
+{
+  auto parameters = ControlParameters().setFaceId(65535);
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // DestroyFace
+
+BOOST_AUTO_TEST_CASE(FaceEvents)
+{
+  auto addedFace = addFace<DummyFace>(); // trigger FACE_EVENT_CREATED notification
+  BOOST_CHECK_NE(addedFace->getId(), -1);
+  int64_t faceId = addedFace->getId();
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+    BOOST_CHECK_NO_THROW(payload = m_responses[0].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+
+  addedFace->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
+  advanceClocks(time::milliseconds(1), 10);
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+    BOOST_CHECK_NO_THROW(payload = m_responses[1].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+  BOOST_CHECK_EQUAL(addedFace->getId(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(EnableDisableLocalControl)
+{
+  auto nonLocalFace = addFace<DummyFace>(true); // clear notification
+  auto localFace = addFace<DummyLocalFace>(true); // clear notification
+  BOOST_CHECK(localFace->isLocal());
+  BOOST_CHECK(!nonLocalFace->isLocal());
+
+  std::vector<Name> commandNames;
+  auto testLocalControl = [&] (const Name& name, const ControlParameters& params, uint64_t faceId) {
+    auto command = makeControlCommandRequest(name, params,
+                                             [faceId] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(faceId);
+                                             });
+    receiveInterest(command);
+    commandNames.push_back(command->getName());
+  };
+
+  auto paramsF = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
+  auto paramsN = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
+
+  // non-existing face: 0~3
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, FACEID_NULL);
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, FACEID_NULL);
+
+  // non-local face: 4~7
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, nonLocalFace->getId());
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, nonLocalFace->getId());
+
+  // enableLocalControl for Incoming FaceId on existing local face:
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, localFace->getId()); // 8
+  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // disableLocalControl for Incoming FaceId on existing local face
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, localFace->getId()); // 9
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // enableLocalControl for NextHop ID on existing local face
+  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, localFace->getId()); // 10
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // disableLocalControl for NextHop ID on existing local face
+  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, localFace->getId()); // 11
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
+  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
+
+  // check responses
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 12);
+  BOOST_CHECK_EQUAL(checkResponse(0,  commandNames[0],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1,  commandNames[1],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(2,  commandNames[2],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(3,  commandNames[3],  ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(4,  commandNames[4],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(5,  commandNames[5],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(6,  commandNames[6],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(7,  commandNames[7],  ControlResponse(412, "Face is non-local")),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(8,  commandNames[8],  makeResponse(200, "OK", paramsF)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(9,  commandNames[9],  makeResponse(200, "OK", paramsF)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(10, commandNames[10], makeResponse(200, "OK", paramsN)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(11, commandNames[11], makeResponse(200, "OK", paramsN)),
+                    CheckResponseResult::OK);
+}
+
+class TestFace : public DummyFace
+{
+public:
+  explicit
+  TestFace(const std::string& uri = "test://")
+    : DummyFace(uri, uri)
+  {
+    getMutableCounters().getNInInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNInDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNInBytes().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutBytes().set(ndn::random::generateWord64());
+  }
+};
+
+// @todo Refactor when ndn::nfd::FaceStatus implementes operator!= and operator<<
+class FaceStatus : public ndn::nfd::FaceStatus
+{
+public:
+  FaceStatus(const ndn::nfd::FaceStatus& s)
+    : ndn::nfd::FaceStatus(s)
+  {
+  }
+};
+
+bool
+operator!=(const FaceStatus& left, const FaceStatus& right)
+{
+  return left.getRemoteUri() != right.getRemoteUri() ||
+    left.getLocalUri() != right.getLocalUri() ||
+    left.getFaceScope() != right.getFaceScope() ||
+    left.getFacePersistency() != right.getFacePersistency() ||
+    left.getLinkType() != right.getLinkType() ||
+    left.getNInInterests() != right.getNInInterests() ||
+    left.getNInDatas() != right.getNInDatas() ||
+    left.getNOutInterests() != right.getNOutInterests() ||
+    left.getNOutDatas() != right.getNOutDatas() ||
+    left.getNInBytes() != right.getNInBytes() ||
+    left.getNOutBytes() != right.getNOutBytes();
+}
+
+std::ostream&
+operator<<(std::ostream &os, const FaceStatus& status)
+{
+  os << "[" << status.getRemoteUri() << ", "
+     << status.getLocalUri() << ", "
+     << status.getFacePersistency() << ", "
+     << status.getLinkType() << ", "
+     << status.getNInInterests() << ", "
+     << status.getNInDatas() << ", "
+     << status.getNOutInterests() << ", "
+     << status.getNOutDatas() << ", "
+     << status.getNInBytes() << ", "
+     << status.getNOutBytes() << "]";
+  return os;
+}
+
+BOOST_AUTO_TEST_CASE(FaceDataset)
+{
+  size_t nEntries = 303;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    addFace<TestFace>(true);
+  }
+
+  receiveInterest(makeInterest("/localhost/nfd/faces/list"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  std::vector<FaceStatus> expectedStatuses, receivedStatuses;
+  std::set<FaceId> faceIds;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    ndn::nfd::FaceStatus decodedStatus;
+    BOOST_REQUIRE_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_REQUIRE(m_faceTable.get(decodedStatus.getFaceId()) != nullptr);
+    faceIds.insert(decodedStatus.getFaceId());
+    receivedStatuses.push_back(decodedStatus);
+    expectedStatuses.push_back(m_faceTable.get(decodedStatus.getFaceId())->getFaceStatus());
+  }
+
+  BOOST_CHECK_EQUAL(faceIds.size(), nEntries);
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedStatuses.begin(), receivedStatuses.end(),
+                                expectedStatuses.begin(), expectedStatuses.end());
+}
+
+BOOST_AUTO_TEST_CASE(FaceQuery)
+{
+  auto face1 = addFace<DummyFace>(true); // dummy://
+  auto face2 = addFace<DummyLocalFace>(true); // dummy://, local
+  auto face3 = addFace<TestFace>(true); // test://
+
+  auto generateQueryName = [] (const ndn::nfd::FaceQueryFilter& filter) {
+    return Name("/localhost/nfd/faces/query").append(filter.wireEncode());
+  };
+
+  auto querySchemeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setUriScheme("dummy"));
+  auto queryIdName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceId(face1->getId()));
+  auto queryScopeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL));
+  auto invalidQueryName =
+    Name("/localhost/nfd/faces/query").append(ndn::makeStringBlock(tlv::Content, "invalid"));
+
+  receiveInterest(makeInterest(querySchemeName)); // face1 and face2 expected
+  receiveInterest(makeInterest(queryIdName)); // face1 expected
+  receiveInterest(makeInterest(queryScopeName)); // face1 and face3 expected
+  receiveInterest(makeInterest(invalidQueryName)); // nack expected
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 4);
+
+  Block content;
+  ndn::nfd::FaceStatus status;
+
+  content = m_responses[0].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face2
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face2->getId(), status.getFaceId());
+
+  content = m_responses[1].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 1); // face1
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+
+  content = m_responses[2].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face3
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face3->getId(), status.getFaceId());
+
+  ControlResponse expectedResponse(400, "malformed filter"); // nack, 400, malformed filter
+  BOOST_CHECK_EQUAL(checkResponse(3, invalidQueryName, expectedResponse, tlv::ContentType_Nack),
+                    CheckResponseResult::OK);
+}
+
+class TestChannel : public Channel
+{
+public:
+  TestChannel(const std::string& uri)
+  {
+    setUri(FaceUri(uri));
+  }
+};
+
+class TestProtocolFactory : public ProtocolFactory
+{
+public:
+  virtual void
+  createFace(const FaceUri& uri,
+             ndn::nfd::FacePersistency persistency,
+             const FaceCreatedCallback& onCreated,
+             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE
+  {
+  }
+
+  virtual std::list<shared_ptr<const Channel>>
+  getChannels() const DECL_OVERRIDE
+  {
+    return m_channels;
+  }
+
+public:
+  shared_ptr<TestChannel>
+  addChannel(const std::string& channelUri)
+  {
+    auto channel = make_shared<TestChannel>(channelUri);
+    m_channels.push_back(channel);
+    return channel;
+  }
+
+private:
+  std::list<shared_ptr<const Channel> > m_channels;
+};
+
+BOOST_AUTO_TEST_CASE(ChannelDataset)
+{
+  auto factory = make_shared<TestProtocolFactory>();
+  m_manager.m_factories["test"] = factory;
+
+  std::map<std::string, shared_ptr<TestChannel>> addedChannels;
+  size_t nEntries = 404;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    auto channel = factory->addChannel("test" + boost::lexical_cast<std::string>(i) + "://");
+    addedChannels[channel->getUri().toString()] = channel;
+  }
+
+  receiveInterest(makeInterest("/localhost/nfd/faces/channels"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    ndn::nfd::ChannelStatus decodedStatus;
+    BOOST_CHECK_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_CHECK(addedChannels.find(decodedStatus.getLocalUri()) != addedChannels.end());
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
