mgmt: moved signing into AppFace, code streamlining, and bug fixes

tests/management: improved callback validation

Fixed bad shared_ptr NULL checks
Fixed bad iterator decrement in InternalFace.sendInterest
Removed semi-useless constants in FibManager
Clarified ControlResponse text messages

Change-Id: Ic327a0b6b57827e401c7c3115d0ee92bae996a34
refs: #1138
diff --git a/daemon/mgmt/app-face.cpp b/daemon/mgmt/app-face.cpp
new file mode 100644
index 0000000..79bf39f
--- /dev/null
+++ b/daemon/mgmt/app-face.cpp
@@ -0,0 +1,17 @@
+/* -*- 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 "app-face.hpp"
+
+namespace nfd {
+
+void
+AppFace::sign(Data& data)
+{
+  m_keyChain.sign(data);
+}
+
+} // namespace nfd
diff --git a/daemon/mgmt/app-face.hpp b/daemon/mgmt/app-face.hpp
index af58cdf..b6e2ab5 100644
--- a/daemon/mgmt/app-face.hpp
+++ b/daemon/mgmt/app-face.hpp
@@ -9,9 +9,11 @@
 
 #include "common.hpp"
 
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
 namespace nfd {
 
-typedef ndn::func_lib::function<void(const Name&, const Interest&)> OnInterest;
+typedef function<void(const Name&, const Interest&)> OnInterest;
 
 class AppFace
 {
@@ -21,10 +23,16 @@
                     OnInterest onInterest) = 0;
 
   virtual void
+  sign(Data& data);
+
+  virtual void
   put(const Data& data) = 0;
 
   virtual
   ~AppFace() { }
+
+protected:
+  ndn::KeyChain m_keyChain;
 };
 
 } // namespace nfd
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 5885e48..69be19f 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -33,41 +33,34 @@
   FibManager::FIB_MANAGER_COMMAND_UNSIGNED_NCOMPS +
   0; // No signed Interest support in mock, otherwise 3 (timestamp, signed info tlv, signature tlv)
 
-const Name::Component FibManager::FIB_MANAGER_COMMAND_VERB_INSERT = "insert";
-const Name::Component FibManager::FIB_MANAGER_COMMAND_VERB_DELETE = "delete";
-const Name::Component FibManager::FIB_MANAGER_COMMAND_VERB_ADD_NEXTHOP = "add-nexthop";
-const Name::Component FibManager::FIB_MANAGER_COMMAND_VERB_REMOVE_NEXTHOP = "remove-nexthop";
-const Name::Component FibManager::FIB_MANAGER_COMMAND_VERB_STRATEGY = "strategy";
-
-
 const FibManager::VerbAndProcessor FibManager::FIB_MANAGER_COMMAND_VERBS[] =
   {
     // Unsupported
 
     // VerbAndProcessor(
-    //                  FibManager::FIB_MANAGER_COMMAND_VERB_INSERT,
+    //                  "insert",
     //                  &FibManager::fibInsert
     //                  ),
 
     // VerbAndProcessor(
-    //                  FibManager::FIB_MANAGER_COMMAND_VERB_DELETE,
+    //                  "delete",
     //                  &FibManager::fibDelete
     //                  ),
 
     VerbAndProcessor(
-                     FibManager::FIB_MANAGER_COMMAND_VERB_ADD_NEXTHOP,
+                     "add-nexthop",
                      &FibManager::fibAddNextHop
                      ),
 
     // Unsupported
 
     // VerbAndProcessor(
-    //                  FibManager::FIB_MANAGER_COMMAND_VERB_REMOVE_NEXTHOP,
+    //                  "remove-nexthop",
     //                  &FibManager::fibRemoveNextHop
     //                  ),
 
     // VerbAndProcessor(
-    //                  FibManager::FIB_MANAGER_COMMAND_VERB_STRATEGY,
+    //                  "strategy",
     //                  &FibManager::fibStrategy
     //                  )
 
@@ -99,7 +92,7 @@
       commandNComps < FIB_MANAGER_COMMAND_SIGNED_NCOMPS)
     {
       NFD_LOG_INFO("Unsigned command: " << command);
-      sendResponse(command, 401, "SIGREQ");
+      sendResponse(command, 401, "Signature required");
 
       return;
     }
@@ -107,7 +100,7 @@
       !FIB_MANAGER_COMMAND_PREFIX.isPrefixOf(command))
     {
       NFD_LOG_INFO("Malformed command: " << command);
-      sendResponse(command, 400, "MALFORMED");
+      sendResponse(command, 400, "Malformed command");
       return;
     }
 
@@ -123,7 +116,7 @@
   else
     {
       NFD_LOG_INFO("Unsupported command verb: " << verb);
-      sendResponse(request.getName(), 404, "UNSUPPORTED");
+      sendResponse(request.getName(), 501, "Unsupported command");
     }
 
 }
@@ -160,7 +153,7 @@
   catch (const ndn::Tlv::Error& e)
     {
       NFD_LOG_INFO("Bad command option parse: " << command);
-      sendResponse(request.getName(), 400, "MALFORMED");
+      sendResponse(request.getName(), 400, "Malformed command");
       return;
     }
 
@@ -168,7 +161,7 @@
   if (false)
     {
       NFD_LOG_INFO("Unauthorized command attempt: " << command);
-      sendResponse(request.getName(), 403, "UNAUTHORIZED");
+      sendResponse(request.getName(), 403, "Unauthorized command");
       return;
     }
 
@@ -177,7 +170,7 @@
                << " Cost: " << options.getCost());
 
   shared_ptr<Face> nextHopFace = m_getFace(options.getFaceId());
-  if (nextHopFace != 0)
+  if (static_cast<bool>(nextHopFace))
     {
       std::pair<shared_ptr<fib::Entry>, bool> insertResult = m_managedFib.insert(options.getName());
       insertResult.first->addNextHop(nextHopFace, options.getCost());
@@ -186,7 +179,7 @@
   else
     {
       NFD_LOG_INFO("Unknown FaceId: " << command);
-      sendResponse(request.getName(), 400, "MALFORMED");
+      sendResponse(request.getName(), 400, "Malformed command");
     }
 }
 
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index 60b2385..d77a2f2 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -55,8 +55,6 @@
   function<shared_ptr<Face>(FaceId)> m_getFace;
   std::map<Name, shared_ptr<fw::Strategy> > m_namespaceToStrategyMap;
 
-
-
   typedef function<void(FibManager*,
                         const Interest&)> VerbProcessor;
 
@@ -77,12 +75,6 @@
   // 5 in mock (see UNSIGNED_NCOMPS), 8 with signed Interest support.
   static const size_t FIB_MANAGER_COMMAND_SIGNED_NCOMPS;
 
-  static const Name::Component FIB_MANAGER_COMMAND_VERB_INSERT;
-  static const Name::Component FIB_MANAGER_COMMAND_VERB_DELETE;
-  static const Name::Component FIB_MANAGER_COMMAND_VERB_ADD_NEXTHOP;
-  static const Name::Component FIB_MANAGER_COMMAND_VERB_REMOVE_NEXTHOP;
-  static const Name::Component FIB_MANAGER_COMMAND_VERB_STRATEGY;
-
   static const VerbAndProcessor FIB_MANAGER_COMMAND_VERBS[];
 
 };
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index ec1baab..7af328f 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -44,7 +44,7 @@
   // match or there is no matching prefix in the map.
 
 
-  if (filter == m_interestFilters.end())
+  if (filter == m_interestFilters.end() && filter != m_interestFilters.begin())
     {
       // We hit the end, check if the previous element
       // is a match
@@ -59,7 +59,7 @@
           NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (before end)");
         }
     }
-  else if (filter->first.isPrefixOf(interestName))
+  else if (filter->first == interestName)
     {
       NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (exact match)");
       filter->second(interestName, interest);
diff --git a/daemon/mgmt/manager-base.cpp b/daemon/mgmt/manager-base.cpp
index 2b27f85..55787b6 100644
--- a/daemon/mgmt/manager-base.cpp
+++ b/daemon/mgmt/manager-base.cpp
@@ -40,7 +40,7 @@
   Data response(name);
   response.setContent(encodedControl);
 
-  m_keyChain.sign(response);
+  m_face->sign(response);
   m_face->put(response);
 }
 
diff --git a/daemon/mgmt/manager-base.hpp b/daemon/mgmt/manager-base.hpp
index fd3bcef..d62b1c0 100644
--- a/daemon/mgmt/manager-base.hpp
+++ b/daemon/mgmt/manager-base.hpp
@@ -8,7 +8,7 @@
 #define NFD_MGMT_MANAGER_BASE_HPP
 
 #include "common.hpp"
-#include <ndn-cpp-dev/security/key-chain.hpp>
+
 
 namespace nfd {
 
@@ -31,7 +31,6 @@
 
 protected:
   shared_ptr<AppFace> m_face;
-   ndn::KeyChain m_keyChain;
 };
 
 
diff --git a/tests/mgmt/fib-manager.cpp b/tests/mgmt/fib-manager.cpp
index fec1f63..b07d11b 100644
--- a/tests/mgmt/fib-manager.cpp
+++ b/tests/mgmt/fib-manager.cpp
@@ -27,6 +27,12 @@
 {
 public:
 
+  FibManagerFixture()
+    : m_callbackFired(false)
+  {
+
+  }
+
   shared_ptr<Face>
   getFace(FaceId id)
   {
@@ -44,31 +50,47 @@
     m_faces.push_back(face);
   }
 
+  void
+  validateControlResponse(const Data& response,
+                          uint32_t expectedCode,
+                          const std::string& expectedText)
+  {
+    m_callbackFired = true;
+    Block controlRaw = response.getContent().blockFromValue();
+
+    ndn::ControlResponse control;
+    control.wireDecode(controlRaw);
+
+    NFD_LOG_DEBUG("received control response"
+                  << " Name: " << response.getName()
+                  << " code: " << control.getCode()
+                  << " text: " << control.getText());
+
+    BOOST_REQUIRE(control.getCode() == expectedCode);
+    BOOST_REQUIRE(control.getText() == expectedText);
+  }
+
+  bool
+  didCallbackFire()
+  {
+    return m_callbackFired;
+  }
+
+  void
+  resetCallbackFired()
+  {
+    m_callbackFired = false;
+  }
+
 private:
   std::vector<shared_ptr<Face> > m_faces;
+  bool m_callbackFired;
 };
 
 
 BOOST_AUTO_TEST_SUITE(MgmtFibManager)
 
-void
-validateControlResponse(const Data& response,
-                        uint32_t expectedCode,
-                        const std::string& expectedText)
-{
-  Block controlRaw = response.getContent().blockFromValue();
 
-  ndn::ControlResponse control;
-  control.wireDecode(controlRaw);
-
-  NFD_LOG_DEBUG("received control response"
-                << " Name: " << response.getName()
-                << " code: " << control.getCode()
-                << " text: " << control.getText());
-
-  BOOST_REQUIRE(control.getCode() == expectedCode);
-  BOOST_REQUIRE(control.getText() == expectedText);
-}
 
 bool
 foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
@@ -81,7 +103,7 @@
 {
   shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(prefix);
 
-  if (entry)
+  if (static_cast<bool>(entry))
     {
       const fib::NextHopList& hops = entry->getNextHops();
       return hops.size() == oldSize + 1 &&
@@ -101,7 +123,7 @@
                           face);
 
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 400, "MALFORMED");
+    bind(&FibManagerFixture::validateControlResponse, &fixture,  _1, 400, "Malformed command");
 
   Interest command("/localhost/nfd/fib");
   face->sendInterest(command);
@@ -117,25 +139,28 @@
                           &fixture, _1),
                           face);
 
+  BOOST_REQUIRE(fixture.didCallbackFire() == false);
+
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 400, "MALFORMED");
+    bind(&FibManagerFixture::validateControlResponse, &fixture, _1, 400, "Malformed command");
 
   Interest command("/localhost/nfd/fib");
   manager.onFibRequest(command);
+
+  BOOST_REQUIRE(fixture.didCallbackFire());
 }
 
-BOOST_AUTO_TEST_CASE(UnsupportedVerb)
+BOOST_FIXTURE_TEST_CASE(UnsupportedVerb, FibManagerFixture)
 {
-  FibManagerFixture fixture;
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 404, "UNSUPPORTED");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 501, "Unsupported command");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -150,23 +175,24 @@
 
   Interest command(commandName);
   manager.onFibRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
 }
 
-BOOST_AUTO_TEST_CASE(UnsignedCommand)
+BOOST_FIXTURE_TEST_CASE(UnsignedCommand, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                      face);
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 200, "OK");
   /// \todo enable once sig checking implement
-    // bind(&validateControlResponse, _1, 401, "SIGREG");
+    // bind(&FibManagerFixture::validateControlResponse, this, _1, 401, "SIGREG");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -182,24 +208,24 @@
   Interest command(commandName);
   manager.onFibRequest(command);
 
+  BOOST_REQUIRE(didCallbackFire());
   BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
 }
 
-BOOST_AUTO_TEST_CASE(UnauthorizedCommand)
+BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                      face);
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 200, "OK");
   /// \todo enable once sig checking implement
-    // bind(&validateControlResponse, _1, 403, "UNAUTHORIZED");
+    // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -215,23 +241,23 @@
   Interest command(commandName);
   manager.onFibRequest(command);
 
+  BOOST_REQUIRE(didCallbackFire());
   BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
 }
 
-BOOST_AUTO_TEST_CASE(BadOptionParse)
+BOOST_FIXTURE_TEST_CASE(BadOptionParse, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                      face);
 
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 400, "MALFORMED");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 400, "Malformed command");
 
   Name commandName("/localhost/nfd/fib");
   commandName.append("add-nexthop");
@@ -239,22 +265,23 @@
 
   Interest command(commandName);
   manager.onFibRequest(command);
+
+  BOOST_REQUIRE(didCallbackFire());
 }
 
-BOOST_AUTO_TEST_CASE(UnknownFaceId)
+BOOST_FIXTURE_TEST_CASE(UnknownFaceId, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                      face);
 
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 400, "MALFORMED");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 400, "Malformed command");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -270,22 +297,22 @@
   Interest command(commandName);
   manager.onFibRequest(command);
 
+  BOOST_REQUIRE(didCallbackFire());
   BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
+BOOST_FIXTURE_TEST_CASE(AddNextHopVerbInitialAdd, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 200, "OK");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -301,23 +328,23 @@
   Interest command(commandName);
   manager.onFibRequest(command);
 
+  BOOST_REQUIRE(didCallbackFire());
   BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
+BOOST_FIXTURE_TEST_CASE(AddNextHopVerbAddToExisting, FibManagerFixture)
 {
-  FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 200, "OK");
 
   // Add faces with cost == FaceID for the name /hello
   // This test assumes:
@@ -338,10 +365,12 @@
 
       Interest command(commandName);
       manager.onFibRequest(command);
+      BOOST_REQUIRE(didCallbackFire());
+      resetCallbackFired();
 
       shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
 
-      if (entry)
+      if (static_cast<bool>(entry))
         {
           const fib::NextHopList& hops = entry->getNextHops();
           for (int j = 1; j <= i; j++)
@@ -356,19 +385,19 @@
     }
 }
 
-BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
+BOOST_FIXTURE_TEST_CASE(AddNextHopVerbUpdateFaceCost, FibManagerFixture)
 {
   FibManagerFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(make_shared<InternalFace>());
   Fib fib;
   FibManager manager(fib,
                      bind(&FibManagerFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
   face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+    bind(&FibManagerFixture::validateControlResponse, this, _1, 200, "OK");
 
   ndn::FibManagementOptions options;
   options.setName("/hello");
@@ -385,6 +414,8 @@
 
     Interest command(commandName);
     manager.onFibRequest(command);
+    BOOST_REQUIRE(didCallbackFire());
+    resetCallbackFired();
   }
 
   {
@@ -398,6 +429,7 @@
 
     Interest command(commandName);
     manager.onFibRequest(command);
+    BOOST_REQUIRE(didCallbackFire());
   }
 
   shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
@@ -405,7 +437,7 @@
   // Add faces with cost == FaceID for the name /hello
   // This test assumes:
   //   FaceIDs are -1 because we don't add them to a forwarder
-  if (entry)
+  if (static_cast<bool>(entry))
     {
       const fib::NextHopList& hops = entry->getNextHops();
       BOOST_REQUIRE(hops.size() == 1);
diff --git a/tests/mgmt/internal-face.cpp b/tests/mgmt/internal-face.cpp
index 1c6f70d..5953fc6 100644
--- a/tests/mgmt/internal-face.cpp
+++ b/tests/mgmt/internal-face.cpp
@@ -23,6 +23,13 @@
 {
 public:
 
+  InternalFaceFixture()
+    : m_onInterestFired(false),
+      m_noOnInterestFired(false)
+  {
+
+  }
+
   shared_ptr<Face>
   getFace(FaceId id)
   {
@@ -34,132 +41,98 @@
   }
 
   void
+  validateOnInterestCallback(const Name& name, const Interest& interest)
+  {
+    m_onInterestFired = true;
+  }
+
+  void
+  validateNoOnInterestCallback(const Name& name, const Interest& interest)
+  {
+    m_noOnInterestFired = true;
+  }
+
+  void
   addFace(shared_ptr<Face> face)
   {
     m_faces.push_back(face);
   }
 
+  bool
+  didOnInterestFire()
+  {
+    return m_onInterestFired;
+  }
+
+  bool
+  didNoOnInterestFire()
+  {
+    return m_noOnInterestFired;
+  }
+
+  void
+  resetOnInterestFired()
+  {
+    m_onInterestFired = false;
+  }
+
+  void
+  resetNoOnInterestFired()
+  {
+    m_noOnInterestFired = false;
+  }
+
 private:
   std::vector<shared_ptr<Face> > m_faces;
+  bool m_onInterestFired;
+  bool m_noOnInterestFired;
 };
 
 BOOST_AUTO_TEST_SUITE(MgmtInternalFace)
 
 void
-validateControlResponse(const Data& response,
-                        uint32_t expectedCode,
-                        const std::string& expectedText)
+validatePutData(bool& called, const Name& expectedName, const Data& data)
 {
-  Block controlRaw = response.getContent().blockFromValue();
-
-  ndn::ControlResponse control;
-  control.wireDecode(controlRaw);
-
-  NFD_LOG_DEBUG("received control response"
-                << " Name: " << response.getName()
-                << " code: " << control.getCode()
-                << " text: " << control.getText());
-
-  BOOST_REQUIRE(control.getCode() == expectedCode);
-  BOOST_REQUIRE(control.getText() == expectedText);
+  called = true;
+  BOOST_CHECK_EQUAL(expectedName, data.getName());
 }
 
-BOOST_AUTO_TEST_CASE(ValidAddNextHop)
+BOOST_FIXTURE_TEST_CASE(PutData, InternalFaceFixture)
 {
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(new InternalFace);
   Fib fib;
   FibManager manager(fib,
                      bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
-  face->onReceiveData +=
-    bind(&validateControlResponse, _1, 200, "OK");
+  bool didPutData = false;
+  Name dataName("/hello");
+  face->onReceiveData += bind(&validatePutData, boost::ref(didPutData), dataName, _1);
 
-  ndn::FibManagementOptions options;
-  options.setName("/hello");
-  options.setFaceId(1);
-  options.setCost(1);
+  Data testData(dataName);
+  face->sign(testData);
+  face->put(testData);
 
-  Block encodedOptions(options.wireEncode());
-
-  Name commandName("/localhost/nfd/fib");
-  commandName.append("add-nexthop");
-  commandName.append(encodedOptions);
-
-  Interest command(commandName);
-  face->sendInterest(command);
-
-  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
-
-  if (entry)
-    {
-      const fib::NextHopList& hops = entry->getNextHops();
-      BOOST_REQUIRE(hops.size() == 1);
-      BOOST_CHECK(hops[0].getCost() == 1);
-    }
-  else
-    {
-      BOOST_FAIL("Failed to find expected fib entry");
-    }
+  BOOST_REQUIRE(didPutData);
 }
 
-BOOST_AUTO_TEST_CASE(InvalidPrefixRegistration)
+BOOST_FIXTURE_TEST_CASE(SendInterestHitEnd, InternalFaceFixture)
 {
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(new InternalFace);
   Fib fib;
   FibManager manager(fib,
                      bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
-                     face);
-
-  face->onReceiveData +=
-    bind(&validateControlResponse, _1, 404, "MALFORMED");
-
-  Interest nonRegInterest("/hello");
-  face->sendInterest(nonRegInterest);
-
-  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
-
-  if (entry)
-    {
-      const fib::NextHopList& hops = entry->getNextHops();
-      BOOST_REQUIRE(hops.size() == 0);
-    }
-}
-
-void
-validateOnInterestCallback(const Name& name, const Interest& interest)
-{
-  NFD_LOG_DEBUG("Reached correct callback");
-}
-
-void
-validateNoOnInterestCallback(const Name& name, const Interest& interest)
-{
-  BOOST_FAIL("Reached wrong callback");
-}
-
-BOOST_AUTO_TEST_CASE(SendInterestHitEnd)
-{
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
-
-  shared_ptr<InternalFace> face(new InternalFace);
-  Fib fib;
-  FibManager manager(fib,
-                     bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
   face->setInterestFilter("/localhost/nfd/fib",
-                          &validateOnInterestCallback);
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                               this, _1, _2));
 
   // generate command whose name is canonically
   // ordered after /localhost/nfd/fib so that
@@ -168,24 +141,27 @@
   Name commandName("/localhost/nfd/fib/end");
   Interest command(commandName);
   face->sendInterest(command);
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
 }
 
 
 
-BOOST_AUTO_TEST_CASE(SendInterestHitBegin)
+BOOST_FIXTURE_TEST_CASE(SendInterestHitBegin, InternalFaceFixture)
 {
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(new InternalFace);
   Fib fib;
   FibManager manager(fib,
                      bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
   face->setInterestFilter("/localhost/nfd/fib",
-                          &validateNoOnInterestCallback);
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
 
   // generate command whose name is canonically
   // ordered before /localhost/nfd/fib so that
@@ -194,30 +170,34 @@
   Name commandName("/localhost/nfd");
   Interest command(commandName);
   face->sendInterest(command);
+
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
 }
 
 
 
-BOOST_AUTO_TEST_CASE(SendInterestHitExact)
+BOOST_FIXTURE_TEST_CASE(SendInterestHitExact, InternalFaceFixture)
 {
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(new InternalFace);
   Fib fib;
   FibManager manager(fib,
                      bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
   face->setInterestFilter("/localhost/nfd/eib",
-                          &validateNoOnInterestCallback);
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
 
   face->setInterestFilter("/localhost/nfd/fib",
-                          &validateOnInterestCallback);
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                           this, _1, _2));
 
   face->setInterestFilter("/localhost/nfd/gib",
-                          &validateNoOnInterestCallback);
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
 
   // generate command whose name exactly matches
   // /localhost/nfd/fib
@@ -225,27 +205,31 @@
   Name commandName("/localhost/nfd/fib");
   Interest command(commandName);
   face->sendInterest(command);
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
 }
 
 
 
-BOOST_AUTO_TEST_CASE(SendInterestHitPrevious)
+BOOST_FIXTURE_TEST_CASE(SendInterestHitPrevious, InternalFaceFixture)
 {
-  InternalFaceFixture fixture;
-  fixture.addFace(make_shared<DummyFace>());
+  addFace(make_shared<DummyFace>());
 
   shared_ptr<InternalFace> face(new InternalFace);
   Fib fib;
   FibManager manager(fib,
                      bind(&InternalFaceFixture::getFace,
-                          &fixture, _1),
+                          this, _1),
                           face);
 
   face->setInterestFilter("/localhost/nfd/fib",
-                          &validateOnInterestCallback);
+                          bind(&InternalFaceFixture::validateOnInterestCallback,
+                               this, _1, _2));
 
   face->setInterestFilter("/localhost/nfd/fib/zzzzzzzzzzzzz/",
-                          &validateNoOnInterestCallback);
+                          bind(&InternalFaceFixture::validateNoOnInterestCallback,
+                               this, _1, _2));
 
   // generate command whose name exactly matches
   // an Interest filter
@@ -253,6 +237,9 @@
   Name commandName("/localhost/nfd/fib/previous");
   Interest command(commandName);
   face->sendInterest(command);
+
+  BOOST_REQUIRE(didOnInterestFire());
+  BOOST_REQUIRE(didNoOnInterestFire() == false);
 }
 
 BOOST_AUTO_TEST_SUITE_END()