diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index 6e06438..a3013f6 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -17,6 +17,11 @@
 {
 }
 
+FaceTable::~FaceTable()
+{
+
+}
+
 void
 FaceTable::add(shared_ptr<Face> face)
 {
@@ -47,4 +52,6 @@
   m_forwarder.getFib().removeNextHopFromAllEntries(face);
 }
 
+
+
 } // namespace nfd
diff --git a/daemon/fw/face-table.hpp b/daemon/fw/face-table.hpp
index 28a4faa..2415568 100644
--- a/daemon/fw/face-table.hpp
+++ b/daemon/fw/face-table.hpp
@@ -23,13 +23,16 @@
   explicit
   FaceTable(Forwarder& forwarder);
 
-  void
+  VIRTUAL_WITH_TESTS
+  ~FaceTable();
+
+  VIRTUAL_WITH_TESTS void
   add(shared_ptr<Face> face);
 
-  void
+  VIRTUAL_WITH_TESTS void
   remove(shared_ptr<Face> face);
 
-  shared_ptr<Face>
+  VIRTUAL_WITH_TESTS shared_ptr<Face>
   get(FaceId id) const;
 
   size_t
diff --git a/daemon/main.cpp b/daemon/main.cpp
index bd511bb..d9867fe 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -9,6 +9,7 @@
 #include "fw/forwarder.hpp"
 #include "mgmt/internal-face.hpp"
 #include "mgmt/fib-manager.hpp"
+#include "mgmt/face-manager.hpp"
 #include "mgmt/local-control-header-manager.hpp"
 #include "face/tcp-factory.hpp"
 
@@ -42,6 +43,7 @@
 static ProgramOptions g_options;
 static Forwarder* g_forwarder;
 static FibManager* g_fibManager;
+static FaceManager* g_faceManager;
 static LocalControlHeaderManager* g_localControlHeaderManager;
 static TcpFactory* g_tcpFactory;
 static shared_ptr<TcpChannel> g_tcpChannel;
@@ -209,6 +211,8 @@
                                 bind(&Forwarder::getFace, g_forwarder, _1),
                                 g_internalFace);
 
+  g_faceManager = new FaceManager(g_forwarder->getFaceTable(), g_internalFace);
+
   g_localControlHeaderManager =
     new LocalControlHeaderManager(bind(&Forwarder::getFace, g_forwarder, _1),
                                   g_internalFace);
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
new file mode 100644
index 0000000..30e3abd
--- /dev/null
+++ b/daemon/mgmt/face-manager.cpp
@@ -0,0 +1,538 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "face-manager.hpp"
+
+#include "core/face-uri.hpp"
+#include "fw/face-table.hpp"
+
+#include "face/tcp-factory.hpp"
+#include "face/udp-factory.hpp"
+#include "face/unix-stream-factory.hpp"
+#include "face/ethernet-factory.hpp"
+
+#ifdef __linux__
+#include <netinet/ether.h>
+#else
+#include <net/ethernet.h>
+#endif
+
+
+namespace nfd {
+
+NFD_LOG_INIT("FaceManager");
+
+const Name FaceManager::COMMAND_PREFIX = "/localhost/nfd/faces";
+
+const size_t FaceManager::COMMAND_UNSIGNED_NCOMPS =
+  FaceManager::COMMAND_PREFIX.size() +
+  1 + // verb
+  1;  // verb options
+
+const size_t FaceManager::COMMAND_SIGNED_NCOMPS =
+  FaceManager::COMMAND_UNSIGNED_NCOMPS +
+  0; // No signed Interest support in mock, otherwise 4 (timestamp, nonce, signed info tlv, signature tlv)
+
+const FaceManager::VerbAndProcessor FaceManager::COMMAND_VERBS[] =
+  {
+    VerbAndProcessor(
+                     Name::Component("create"),
+                     &FaceManager::createFace
+                     ),
+
+    VerbAndProcessor(
+                     Name::Component("destroy"),
+                     &FaceManager::destroyFace
+                     ),
+  };
+
+
+
+FaceManager::FaceManager(FaceTable& faceTable,
+                         shared_ptr<AppFace> face)
+  : ManagerBase(face)
+  , m_faceTable(faceTable)
+  , m_verbDispatch(COMMAND_VERBS,
+                   COMMAND_VERBS +
+                   (sizeof(COMMAND_VERBS) / sizeof(VerbAndProcessor)))
+{
+  face->setInterestFilter("/localhost/nfd/faces",
+                          bind(&FaceManager::onFaceRequest, this, _2));
+}
+
+void
+FaceManager::setConfigFile(ConfigFile& configFile)
+{
+  configFile.addSectionHandler("face_system",
+                               bind(&FaceManager::onConfig, this, _1, _2));
+}
+
+
+void
+FaceManager::onConfig(const ConfigSection& configSection, bool isDryRun)
+{
+  bool hasSeenUnix = false;
+  bool hasSeenTcp = false;
+  bool hasSeenUdp = false;
+  bool hasSeenEther = false;
+
+  for (ConfigSection::const_iterator item = configSection.begin();
+       item != configSection.end();
+       ++item)
+    {
+      if (item->first == "unix")
+        {
+          if (hasSeenUnix)
+            throw Error("Duplicate \"unix\" section");
+          hasSeenUnix = true;
+
+          processSectionUnix(item->second, isDryRun);
+        }
+      else if (item->first == "tcp")
+        {
+          if (hasSeenTcp)
+            throw Error("Duplicate \"tcp\" section");
+          hasSeenTcp = true;
+
+          processSectionTcp(item->second, isDryRun);
+        }
+      else if (item->first == "udp")
+        {
+          if (hasSeenUdp)
+            throw Error("Duplicate \"udp\" section");
+          hasSeenUdp = true;
+
+          processSectionUdp(item->second, isDryRun);
+        }
+      else if (item->first == "ether")
+        {
+          if (hasSeenEther)
+            throw Error("Duplicate \"ether\" section");
+          hasSeenEther = true;
+
+          processSectionEther(item->second, isDryRun);
+        }
+      else
+        {
+          throw Error("Unrecognized option \"" + item->first + "\"");
+        }
+    }
+}
+
+void
+FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the unix section contains settings of UNIX stream faces and channels
+  // unix
+  // {
+  //   listen yes ; set to 'no' to disable UNIX stream listener, default 'yes'
+  //   path /var/run/nfd.sock ; UNIX stream listener path
+  // }
+
+  bool needToListen = true;
+  std::string path = "/var/run/nfd.sock";
+
+  for (ConfigSection::const_iterator i = configSection.begin();
+       i != configSection.end();
+       ++i)
+    {
+      if (i->first == "path")
+        {
+          path = i->second.get_value<std::string>();
+        }
+      else if (i->first == "listen")
+        {
+          needToListen = parseYesNo(i, i->first, "unix");
+        }
+      else
+        {
+          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
+        }
+    }
+
+  if (!isDryRun)
+    {
+      shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
+      shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
+
+      if (needToListen)
+        {
+          // Should acceptFailed callback be used somehow?
+          unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                              UnixStreamChannel::ConnectFailedCallback());
+        }
+
+      m_factories.insert(std::make_pair("unix", factory));
+    }
+}
+
+void
+FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the tcp section contains settings of TCP faces and channels
+  // tcp
+  // {
+  //   listen yes ; set to 'no' to disable TCP listener, default 'yes'
+  //   port 6363 ; TCP listener port number
+  // }
+
+  std::string port = "6363";
+  bool needToListen = true;
+
+  for (ConfigSection::const_iterator i = configSection.begin();
+       i != configSection.end();
+       ++i)
+    {
+      if (i->first == "port")
+        {
+          port = i->second.get_value<std::string>();
+        }
+      else if (i->first == "listen")
+        {
+          needToListen = parseYesNo(i, i->first, "tcp");
+        }
+      else
+        {
+          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
+        }
+    }
+
+  if (!isDryRun)
+    {
+      shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(boost::cref(port));
+
+      using namespace boost::asio::ip;
+
+      shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
+
+      if (needToListen)
+        {
+          // Should acceptFailed callback be used somehow?
+
+          ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                              TcpChannel::ConnectFailedCallback());
+          ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                              TcpChannel::ConnectFailedCallback());
+        }
+
+      m_factories.insert(std::make_pair("tcp", factory));
+      m_factories.insert(std::make_pair("tcp4", factory));
+      m_factories.insert(std::make_pair("tcp6", factory));
+    }
+}
+
+void
+FaceManager::processSectionUdp(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the udp section contains settings of UDP faces and channels
+  // udp
+  // {
+  //   port 6363 ; UDP unicast port number
+  //   idle_timeout 30 ; idle time (seconds) before closing a UDP unicast face
+  //   keep_alive_interval 25; interval (seconds) between keep-alive refreshes
+
+  //   ; NFD creates one UDP multicast face per NIC
+  //   mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
+  //   mcast_port 56363 ; UDP multicast port number
+  //   mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
+  // }
+
+  std::string port = "6363";
+  size_t timeout = 30;
+  size_t keepAliveInterval = 25;
+  bool useMcast = true;
+  std::string mcastPort = "56363";
+  std::string mcastGroup;
+
+  for (ConfigSection::const_iterator i = configSection.begin();
+       i != configSection.end();
+       ++i)
+    {
+      if (i->first == "port")
+        {
+          port = i->second.get_value<std::string>();
+        }
+      else if (i->first == "idle_timeout")
+        {
+          try
+            {
+              timeout = i->second.get_value<size_t>();
+            }
+          catch (const std::exception& e)
+            {
+              throw ConfigFile::Error("Invalid value for option \"" +
+                                      i->first + "\" in \"udp\" section");
+            }
+        }
+      else if (i->first == "keep_alive_interval")
+        {
+          try
+            {
+              keepAliveInterval = i->second.get_value<size_t>();
+            }
+          catch (const std::exception& e)
+            {
+              throw ConfigFile::Error("Invalid value for option \"" +
+                                      i->first + "\" in \"udp\" section");
+            }
+        }
+      else if (i->first == "mcast")
+        {
+          useMcast = parseYesNo(i, i->first, "udp");
+        }
+      else if (i->first == "mcast_port")
+        {
+          mcastPort = i->second.get_value<std::string>();
+        }
+      else if (i->first == "mcast_group")
+        {
+          using namespace boost::asio::ip;
+          mcastGroup = i->second.get_value<std::string>();
+          try
+            {
+              address mcastGroupTest = address::from_string(mcastGroup);
+              if (!mcastGroupTest.is_v4())
+                {
+                  throw ConfigFile::Error("Invalid value for option \"" +
+                                          i->first + "\" in \"udp\" section");
+                }
+            }
+          catch(const std::runtime_error& e)
+            {
+              throw ConfigFile::Error("Invalid value for option \"" +
+                                      i->first + "\" in \"udp\" section");
+            }
+        }
+      else
+        {
+          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
+        }
+    }
+
+  /// \todo what is keep alive interval used for?
+
+  if (!isDryRun)
+    {
+      shared_ptr<UdpFactory> factory = make_shared<UdpFactory>(boost::cref(port));
+
+      shared_ptr<UdpChannel> ipv4Channel =
+        factory->createChannel("0.0.0.0", port, time::seconds(timeout));
+      shared_ptr<UdpChannel> ipv6Channel =
+        factory->createChannel("::", port, time::seconds(timeout));
+
+      m_factories.insert(std::make_pair("udp", factory));
+      m_factories.insert(std::make_pair("udp4", factory));
+      m_factories.insert(std::make_pair("udp6", factory));
+
+      if (useMcast)
+        {
+          /// \todo create one multicast face per NIC
+          NFD_LOG_WARN("multicast faces are not implemented");
+        }
+    }
+}
+
+void
+FaceManager::processSectionEther(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the ether section contains settings of Ethernet faces and channels
+  // ether
+  // {
+  //   ; NFD creates one Ethernet multicast face per NIC
+  //   mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
+  //   mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
+  // }
+
+  bool useMcast = true;
+  std::string mcastGroup;
+
+  for (ConfigSection::const_iterator i = configSection.begin();
+       i != configSection.end();
+       ++i)
+    {
+      if (i->first == "mcast")
+        {
+          useMcast = parseYesNo(i, i->first, "ether");
+        }
+
+      else if (i->first == "mcast_group")
+        {
+          const std::string mcastGroup = i->second.get_value<std::string>();
+          /// \todo change to use ethernet::Address::fromString
+          if (!ether_aton(mcastGroup.c_str()))
+            {
+              throw ConfigFile::Error("Invalid value for option \"" +
+                                      i->first + "\" in \"ether\" section");
+            }
+        }
+      else
+        {
+          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
+        }
+    }
+
+  if (!isDryRun)
+    {
+      shared_ptr<EthernetFactory> factory = make_shared<EthernetFactory>();
+      m_factories.insert(std::make_pair("ether", factory));
+
+      if (useMcast)
+        {
+          /// \todo create one multicast face per NIC
+          NFD_LOG_WARN("multicast faces are not implemented");
+        }
+    }
+}
+
+
+void
+FaceManager::onFaceRequest(const Interest& request)
+{
+  const Name& command = request.getName();
+  const size_t commandNComps = command.size();
+
+  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
+      commandNComps < COMMAND_SIGNED_NCOMPS)
+    {
+      NFD_LOG_INFO("command result: unsigned verb: " << command);
+      sendResponse(command, 401, "Signature required");
+
+      return;
+    }
+  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
+           !COMMAND_PREFIX.isPrefixOf(command))
+    {
+      NFD_LOG_INFO("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  onValidatedFaceRequest(request.shared_from_this());
+}
+
+void
+FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
+{
+  const Name& command = request->getName();
+  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
+
+  VerbDispatchTable::const_iterator verbProcessor = m_verbDispatch.find (verb);
+  if (verbProcessor != m_verbDispatch.end())
+    {
+      ndn::nfd::FaceManagementOptions options;
+      if (!extractOptions(*request, options))
+        {
+          sendResponse(command, 400, "Malformed command");
+          return;
+        }
+
+      /// \todo authorize command
+      if (false)
+        {
+          NFD_LOG_INFO("command result: unauthorized verb: " << command);
+          sendResponse(command, 403, "Unauthorized command");
+          return;
+        }
+
+      NFD_LOG_INFO("command result: processing verb: " << verb);
+      (verbProcessor->second)(this, command, options);
+    }
+  else
+    {
+      NFD_LOG_INFO("command result: unsupported verb: " << verb);
+      sendResponse(command, 501, "Unsupported command");
+    }
+
+}
+
+bool
+FaceManager::extractOptions(const Interest& request,
+                            ndn::nfd::FaceManagementOptions& extractedOptions)
+{
+  const Name& command = request.getName();
+  const size_t optionCompIndex =
+    COMMAND_PREFIX.size() + 1;
+
+  try
+    {
+      Block rawOptions = request.getName()[optionCompIndex].blockFromValue();
+      extractedOptions.wireDecode(rawOptions);
+    }
+  catch (const ndn::Tlv::Error& e)
+    {
+      NFD_LOG_INFO("Bad command option parse: " << command);
+      return false;
+    }
+  NFD_LOG_DEBUG("Options parsed OK");
+  return true;
+}
+
+void
+FaceManager::onCreated(const Name& requestName,
+                       ndn::nfd::FaceManagementOptions& options,
+                       const shared_ptr<Face>& newFace)
+{
+  m_faceTable.add(newFace);
+  options.setFaceId(newFace->getId());
+
+  NFD_LOG_INFO("Created Face ID " << newFace->getId());
+
+  ndn::nfd::ControlResponse response;
+  setResponse(response, 200, "Success", options.wireEncode());
+  sendResponse(requestName, response);
+}
+
+void
+FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
+{
+  NFD_LOG_INFO("Failed to create face: " << reason);
+  sendResponse(requestName, 400, "Failed to create face");
+}
+
+void
+FaceManager::createFace(const Name& requestName,
+                        ndn::nfd::FaceManagementOptions& options)
+{
+  FaceUri uri;
+  if (!uri.parse(options.getUri()))
+    {
+      sendResponse(requestName, 400, "Malformed command");
+      return;
+    }
+
+  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
+  if (factory == m_factories.end())
+    {
+      sendResponse(requestName, 501, "Unsupported protocol");
+      return;
+    }
+
+  factory->second->createFace(uri,
+                              bind(&FaceManager::onCreated, this, requestName, options, _1),
+                              bind(&FaceManager::onConnectFailed, this, requestName, _1));
+}
+
+
+void
+FaceManager::destroyFace(const Name& requestName,
+                         ndn::nfd::FaceManagementOptions& options)
+{
+  shared_ptr<Face> target = m_faceTable.get(options.getFaceId());
+  if (target)
+    {
+      m_faceTable.remove(target);
+      target->close();
+    }
+  sendResponse(requestName, 200, "Success");
+}
+
+FaceManager::~FaceManager()
+{
+
+}
+
+} // namespace nfd
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
new file mode 100644
index 0000000..87574cd
--- /dev/null
+++ b/daemon/mgmt/face-manager.hpp
@@ -0,0 +1,153 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_MGMT_FACE_MANAGER_HPP
+#define NFD_MGMT_FACE_MANAGER_HPP
+
+#include "common.hpp"
+#include "face/face.hpp"
+#include "mgmt/app-face.hpp"
+#include "mgmt/manager-base.hpp"
+#include "mgmt/config-file.hpp"
+
+#include <ndn-cpp-dev/management/nfd-face-management-options.hpp>
+#include <ndn-cpp-dev/management/nfd-control-response.hpp>
+
+namespace nfd {
+
+const std::string FACE_MANAGER_PRIVILEGE = "faces";
+class FaceTable;
+class ProtocolFactory;
+
+class FaceManager : public ManagerBase
+{
+public:
+  struct Error : public ManagerBase::Error
+  {
+    Error(const std::string& what) : ManagerBase::Error(what) {}
+  };
+
+  /**
+   * \throws FaceManager::Error if localPort is an invalid port number
+   */
+
+  FaceManager(FaceTable& faceTable,
+              shared_ptr<AppFace> face);
+
+  /** \brief Subscribe to a face management section(s) for the config file
+   */
+  void
+  setConfigFile(ConfigFile& configFile);
+
+  void
+  onFaceRequest(const Interest& request);
+
+  VIRTUAL_WITH_TESTS
+  ~FaceManager();
+
+PROTECTED_WITH_TESTS_ELSE_PRIVATE:
+
+  void
+  onValidatedFaceRequest(const shared_ptr<const Interest>& request);
+
+  VIRTUAL_WITH_TESTS void
+  createFace(const Name& requestName,
+             ndn::nfd::FaceManagementOptions& options);
+
+  VIRTUAL_WITH_TESTS void
+  destroyFace(const Name& requestName,
+              ndn::nfd::FaceManagementOptions& options);
+
+  bool
+  extractOptions(const Interest& request,
+                 ndn::nfd::FaceManagementOptions& extractedOptions);
+
+  void
+  onCreated(const Name& requestName,
+            ndn::nfd::FaceManagementOptions& options,
+            const shared_ptr<Face>& newFace);
+
+  void
+  onConnectFailed(const Name& requestName, const std::string& reason);
+
+private:
+  void
+  onConfig(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionUnix(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionTcp(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionUdp(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionEther(const ConfigSection& configSection, bool isDryRun);
+
+  /** \brief parse a config option that can be either "yes" or "no"
+   *  \throw ConfigFile::Error value is neither "yes" nor "no"
+   *  \return true if "yes", false if "no"
+   */
+  bool
+  parseYesNo(const ConfigSection::const_iterator& i,
+             const std::string& optionName,
+             const std::string& sectionName);
+
+private:
+  typedef std::map< std::string/*protocol*/, shared_ptr<ProtocolFactory> > FactoryMap;
+  FactoryMap m_factories;
+  FaceTable& m_faceTable;
+  //
+
+  typedef function<void(FaceManager*,
+                        const Name&,
+                        ndn::nfd::FaceManagementOptions&)> VerbProcessor;
+
+  typedef std::map<Name::Component, VerbProcessor> VerbDispatchTable;
+
+  typedef std::pair<Name::Component, VerbProcessor> VerbAndProcessor;
+
+  const VerbDispatchTable m_verbDispatch;
+
+  static const Name COMMAND_PREFIX; // /localhost/nfd/fib
+
+  // number of components in an invalid, but not malformed, unsigned command.
+  // (/localhost/nfd/fib + verb + options) = 5
+  static const size_t COMMAND_UNSIGNED_NCOMPS;
+
+  // number of components in a valid signed Interest.
+  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
+  static const size_t COMMAND_SIGNED_NCOMPS;
+
+  static const VerbAndProcessor COMMAND_VERBS[];
+};
+
+inline bool
+FaceManager::parseYesNo(const ConfigSection::const_iterator& i,
+                        const std::string& optionName,
+                        const std::string& sectionName)
+{
+  const std::string value = i->second.get_value<std::string>();
+  if (value == "yes")
+    {
+      return true;
+    }
+  else if (value == "no")
+    {
+      return false;
+    }
+
+  throw ConfigFile::Error("Invalid value for option \"" +
+                          optionName + "\" in \"" +
+                          sectionName + "\" section");
+
+}
+
+} // namespace nfd
+
+#endif // NFD_MGMT_FACE_MANAGER_HPP
diff --git a/tests/mgmt/face-manager.cpp b/tests/mgmt/face-manager.cpp
new file mode 100644
index 0000000..92dc680
--- /dev/null
+++ b/tests/mgmt/face-manager.cpp
@@ -0,0 +1,932 @@
+// /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+// /**
+//  * Copyright (C) 2014 Named Data Networking Project
+//  * See COPYING for copyright and distribution information.
+//  */
+
+#include "mgmt/face-manager.hpp"
+#include "mgmt/internal-face.hpp"
+#include "face/face.hpp"
+#include "../face/dummy-face.hpp"
+#include "fw/face-table.hpp"
+#include "fw/forwarder.hpp"
+
+#include "common.hpp"
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT("FaceManagerTest");
+
+class TestDummyFace : public DummyFace
+{
+public:
+
+  TestDummyFace()
+    : m_closeFired(false)
+  {
+
+  }
+
+  virtual
+  ~TestDummyFace()
+  {
+
+  }
+
+  virtual void
+  close()
+  {
+    m_closeFired = true;
+  }
+
+  bool
+  didCloseFire() const
+  {
+    return m_closeFired;
+  }
+
+private:
+  bool m_closeFired;
+};
+
+class TestFaceTable : public FaceTable
+{
+public:
+  TestFaceTable(Forwarder& forwarder)
+    : FaceTable(forwarder),
+      m_addFired(false),
+      m_removeFired(false),
+      m_getFired(false),
+      m_dummy(make_shared<TestDummyFace>())
+  {
+
+  }
+
+  virtual
+  ~TestFaceTable()
+  {
+
+  }
+
+  virtual void
+  add(shared_ptr<Face> face)
+  {
+    m_addFired = true;
+  }
+
+  virtual void
+  remove(shared_ptr<Face> face)
+  {
+    m_removeFired = true;
+  }
+
+  virtual shared_ptr<Face>
+  get(FaceId id) const
+  {
+    m_getFired = true;
+    return m_dummy;
+  }
+
+  bool
+  didAddFire() const
+  {
+    return m_addFired;
+  }
+
+  bool
+  didRemoveFire() const
+  {
+    return m_removeFired;
+  }
+
+  bool
+  didGetFire() const
+  {
+    return m_getFired;
+  }
+
+  void
+  reset()
+  {
+    m_addFired = false;
+    m_removeFired = false;
+    m_getFired = false;
+  }
+
+  shared_ptr<TestDummyFace>&
+  getDummyFace()
+  {
+    return m_dummy;
+  }
+
+private:
+  bool m_addFired;
+  bool m_removeFired;
+  mutable bool m_getFired;
+  shared_ptr<TestDummyFace> m_dummy;
+};
+
+
+class TestFaceTableFixture : public BaseFixture
+{
+public:
+  TestFaceTableFixture()
+    : m_faceTable(m_forwarder)
+  {
+
+  }
+
+  virtual
+  ~TestFaceTableFixture()
+  {
+
+  }
+
+protected:
+  Forwarder m_forwarder;
+  TestFaceTable m_faceTable;
+};
+
+class TestFaceManagerCommon
+{
+public:
+  TestFaceManagerCommon()
+    : m_face(make_shared<InternalFace>()),
+      m_callbackFired(false)
+  {
+
+  }
+
+  virtual
+  ~TestFaceManagerCommon()
+  {
+
+  }
+
+  shared_ptr<InternalFace>&
+  getFace()
+  {
+    return m_face;
+  }
+
+  void
+  validateControlResponseCommon(const Data& response,
+                                const Name& expectedName,
+                                uint32_t expectedCode,
+                                const std::string& expectedText,
+                                ControlResponse& control)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    control.wireDecode(controlRaw);
+
+    // NFD_LOG_DEBUG("received control response"
+    //               << " Name: " << response.getName()
+    //               << " code: " << control.getCode()
+    //               << " text: " << control.getText());
+
+    BOOST_CHECK_EQUAL(response.getName(), expectedName);
+    BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
+    BOOST_CHECK_EQUAL(control.getText(), expectedText);
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    if (!control.getBody().empty())
+      {
+        BOOST_FAIL("found unexpected control response body");
+      }
+  }
+
+  void
+  validateControlResponse(const Data& response,
+                          const Name& expectedName,
+                          uint32_t expectedCode,
+                          const std::string& expectedText,
+                          const Block& expectedBody)
+  {
+    ControlResponse control;
+    validateControlResponseCommon(response, expectedName,
+                                  expectedCode, expectedText, control);
+
+    BOOST_REQUIRE(!control.getBody().empty());
+    BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
+
+    BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
+                       expectedBody.value_size()) == 0);
+
+  }
+
+  bool
+  didCallbackFire() const
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
+protected:
+  shared_ptr<InternalFace> m_face;
+
+private:
+  bool m_callbackFired;
+};
+
+class FaceManagerFixture : public TestFaceTableFixture, public TestFaceManagerCommon
+{
+public:
+  FaceManagerFixture()
+    : m_manager(m_faceTable, m_face)
+  {
+    m_manager.setConfigFile(m_config);
+  }
+
+  void
+  parseConfig(const std::string configuration, bool isDryRun)
+  {
+    m_config.parse(configuration, isDryRun);
+  }
+
+  virtual
+  ~FaceManagerFixture()
+  {
+
+  }
+
+  FaceManager&
+  getManager()
+  {
+    return m_manager;
+  }
+
+  bool
+  didFaceTableAddFire() const
+  {
+    return m_faceTable.didAddFire();
+  }
+
+  bool
+  didFaceTableRemoveFire() const
+  {
+    return m_faceTable.didRemoveFire();
+  }
+
+  bool
+  didFaceTableGetFire() const
+  {
+    return m_faceTable.didGetFire();
+  }
+
+  void
+  resetFaceTable()
+  {
+    m_faceTable.reset();
+  }
+
+private:
+  FaceManager m_manager;
+  ConfigFile m_config;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceManagerFixture)
+
+bool
+isExpectedException(const ConfigFile::Error& error, const std::string& expectedMessage)
+{
+  if (error.what() != expectedMessage)
+    {
+      NFD_LOG_ERROR("expected: " << expectedMessage << "\tgot: " << error.what());
+    }
+  return error.what() == expectedMessage;
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnix)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen yes\n"
+    "    path /tmp/nfd.sock\n"
+    "  }\n"
+    "}\n";
+  BOOST_TEST_CHECKPOINT("Calling parse");
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen yes\n"
+    "    path /var/run/nfd.sock\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"listen\" in \"unix\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUnixUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"unix\" section"));
+}
+
+
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 6363\n"
+    "  }\n"
+    "}\n";
+  try
+    {
+      parseConfig(CONFIG, false);
+    }
+  catch (const std::runtime_error& e)
+    {
+      const std::string reason = e.what();
+      if (reason.find("Address in use") != std::string::npos)
+        {
+          BOOST_FAIL(reason);
+        }
+    }
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 6363\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"listen\" in \"tcp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionTcpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"tcp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\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, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpDryRun)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\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_AUTO_TEST_CASE(TestProcessSectionUdpBadIdleTimeout)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    idle_timeout hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"idle_timeout\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroup)
+{
+  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_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroupV6)
+{
+  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_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionUdpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"udp\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEther)
+{
+  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, false));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherDryRun)
+{
+  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_AUTO_TEST_CASE(TestProcessSectionEtherBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast\" in \"ether\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Invalid value for option \"mcast_group\" in \"ether\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestProcessSectionEtherUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
+                        bind(&isExpectedException, _1,
+                             "Unrecognized option \"hello\" in \"ether\" section"));
+}
+
+BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this,  _1,
+         command->getName(), 400, "Malformed command");
+
+  getFace()->sendInterest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_AUTO_TEST_CASE(MalformedCommmand)
+{
+  shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+/// \todo add tests for unsigned and unauthorized commands
+
+BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+{
+  ndn::nfd::FaceManagementOptions options;
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("unsupported");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&FaceManagerFixture::validateControlResponse, this, _1,
+         command->getName(), 501, "Unsupported command");
+
+  getManager().onFaceRequest(*command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+class ValidatedFaceRequestFixture : public TestFaceTableFixture,
+                                    public TestFaceManagerCommon,
+                                    public FaceManager
+{
+public:
+
+  ValidatedFaceRequestFixture()
+    : FaceManager(TestFaceTableFixture::m_faceTable, TestFaceManagerCommon::m_face),
+      m_createFaceFired(false),
+      m_destroyFaceFired(false)
+  {
+
+  }
+
+  virtual void
+  createFace(const Name& requestName,
+             ndn::nfd::FaceManagementOptions& options)
+  {
+    m_createFaceFired = true;
+  }
+
+  virtual void
+  destroyFace(const Name& requestName,
+              ndn::nfd::FaceManagementOptions& options)
+  {
+    m_destroyFaceFired = true;
+  }
+
+  virtual
+  ~ValidatedFaceRequestFixture()
+  {
+
+  }
+
+  bool
+  didCreateFaceFire() const
+  {
+    return m_createFaceFired;
+  }
+
+  bool
+  didDestroyFaceFire() const
+  {
+    return m_destroyFaceFired;
+  }
+
+private:
+  bool m_createFaceFired;
+  bool m_destroyFaceFired;
+};
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestBadOptionParse, ValidatedFaceRequestFixture)
+{
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append("NotReallyOptions");
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  getFace()->onReceiveData +=
+    bind(&ValidatedFaceRequestFixture::validateControlResponse, this, _1,
+         command->getName(), 400, "Malformed command");
+
+  onValidatedFaceRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestCreateFace, ValidatedFaceRequestFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  onValidatedFaceRequest(command);
+  BOOST_CHECK(didCreateFaceFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestDestroyFace, ValidatedFaceRequestFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("destroy");
+  commandName.append(encodedOptions);
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+
+  onValidatedFaceRequest(command);
+  BOOST_CHECK(didDestroyFaceFire());
+}
+
+class FaceFixture : public TestFaceTableFixture,
+                          public TestFaceManagerCommon,
+                          public FaceManager
+{
+public:
+  FaceFixture()
+    : FaceManager(TestFaceTableFixture::m_faceTable, TestFaceManagerCommon::m_face)
+  {
+
+  }
+
+  virtual
+  ~FaceFixture()
+  {
+
+  }
+};
+
+BOOST_FIXTURE_TEST_CASE(CreateFaceBadUri, FaceFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp:/127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedOptions);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         commandName, 400, "Malformed command");
+
+  createFace(commandName, options);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateFaceUnknownScheme, FaceFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  // this will be an unsupported protocol because no factories have been
+  // added to the face manager
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedOptions);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         commandName, 501, "Unsupported protocol");
+
+  createFace(commandName, options);
+
+  BOOST_REQUIRE(didCallbackFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(OnCreated, FaceFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedOptions);
+
+  ndn::nfd::FaceManagementOptions resultOptions;
+  resultOptions.setUri("tcp://127.0.0.1");
+  resultOptions.setFaceId(-1);
+
+  Block encodedResultOptions(resultOptions.wireEncode());
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         commandName, 200, "Success", encodedResultOptions);
+
+  onCreated(commandName, options, make_shared<DummyFace>());
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_CHECK(TestFaceTableFixture::m_faceTable.didAddFire());
+}
+
+BOOST_FIXTURE_TEST_CASE(OnConnectFailed, FaceFixture)
+{
+    ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(encodedOptions);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         commandName, 400, "Failed to create face");
+
+  onConnectFailed(commandName, "unit-test-reason");
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_CHECK_EQUAL(TestFaceTableFixture::m_faceTable.didAddFire(), false);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(DestroyFace, FaceFixture)
+{
+  ndn::nfd::FaceManagementOptions options;
+  options.setUri("tcp://127.0.0.1");
+
+  Block encodedOptions(options.wireEncode());
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("destroy");
+  commandName.append(encodedOptions);
+
+  getFace()->onReceiveData +=
+    bind(&FaceFixture::validateControlResponse, this, _1,
+         commandName, 200, "Success");
+
+  destroyFace(commandName, options);
+
+  BOOST_REQUIRE(didCallbackFire());
+  BOOST_CHECK(TestFaceTableFixture::m_faceTable.didRemoveFire());
+  BOOST_CHECK(TestFaceTableFixture::m_faceTable.getDummyFace()->didCloseFire());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd
+
