rib: Perform FIB updates before modifying RIB

refs: #1941

Change-Id: I1457f71ddd1c120daae48308d5cc02a7c0ecf93d
diff --git a/tests/rib/fib-updates-common.hpp b/tests/rib/fib-updates-common.hpp
index 98da032..34ae41d 100644
--- a/tests/rib/fib-updates-common.hpp
+++ b/tests/rib/fib-updates-common.hpp
@@ -23,48 +23,34 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "rib-test-common.hpp"
+#include "rib/fib-updater.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
 namespace nfd {
 namespace rib {
 namespace tests {
 
-inline Route
-createRoute(uint64_t faceId, uint64_t origin, uint64_t cost, uint64_t flags)
-{
-  Route temp;
-  temp.faceId = faceId;
-  temp.origin = origin;
-  temp.cost = cost;
-  temp.flags = flags;
-
-  return temp;
-}
-
 inline bool
-compareNameFaceIdCostAction(const shared_ptr<const FibUpdate>& lhs,
-                            const shared_ptr<const FibUpdate>& rhs)
+compareNameFaceIdCostAction(const FibUpdate& lhs, const FibUpdate& rhs)
 {
-  if (lhs->name < rhs->name)
-    {
+  if (lhs.name < rhs.name) {
+    return true;
+  }
+  else if (lhs.name == rhs.name) {
+    if (lhs.faceId < rhs.faceId) {
       return true;
     }
-  else if (lhs->name == rhs->name)
-    {
-      if (lhs->faceId < rhs->faceId)
-        {
-          return true;
-        }
-      else if (lhs->faceId == rhs->faceId)
-        {
-          if (lhs->cost < rhs->cost)
-            {
-              return true;
-            }
-          else if (lhs->cost == rhs->cost)
-            {
-              return lhs->action < rhs->action;
-            }
-        }
+    else if (lhs.faceId == rhs.faceId) {
+      if (lhs.cost < rhs.cost) {
+        return true;
+      }
+      else if (lhs.cost == rhs.cost) {
+        return lhs.action < rhs.action;
+      }
     }
+  }
 
   return false;
 }
@@ -72,39 +58,118 @@
 class FibUpdatesFixture : public nfd::tests::BaseFixture
 {
 public:
+  FibUpdatesFixture()
+    : face(ndn::util::makeDummyClientFace())
+    , controller(*face, keyChain)
+    , fibUpdater(rib, controller)
+  {
+  }
+
   void
   insertRoute(const Name& name, uint64_t faceId, uint64_t origin, uint64_t cost, uint64_t flags)
   {
-    rib::Route route;
-    route.faceId = faceId;
-    route.origin = origin;
-    route.cost = cost;
-    route.flags = flags;
+    Route route = createRoute(faceId, origin, cost, flags);
 
-    rib.insert(name, route);
+    RibUpdate update;
+    update.setAction(RibUpdate::REGISTER)
+          .setName(name)
+          .setRoute(route);
+
+    simulateSuccessfulResponse(update);
   }
 
   void
   eraseRoute(const Name& name, uint64_t faceId, uint64_t origin)
   {
-    rib::Route route;
-    route.faceId = faceId;
-    route.origin = origin;
+    Route route = createRoute(faceId, origin, 0, 0);
 
-    rib.erase(name, route);
+    RibUpdate update;
+    update.setAction(RibUpdate::UNREGISTER)
+          .setName(name)
+          .setRoute(route);
+
+    simulateSuccessfulResponse(update);
+  }
+
+  void
+  onSendBatchFromQueue(const RibUpdateBatch& batch)
+  {
+    Rib::UpdateSuccessCallback managerCallback = bind(&FibUpdatesFixture::onSuccess, this);
+
+    // Only receive callback after the first send
+    rib.m_onSendBatchFromQueue = nullptr;
+
+    rib.onFibUpdateSuccess(batch, fibUpdater.m_inheritedRoutes, managerCallback);
+  }
+
+  void
+  destroyFace(uint64_t faceId)
+  {
+    rib.m_onSendBatchFromQueue = bind(&FibUpdatesFixture::onSendBatchFromQueue, this, _1);
+
+    rib.beginRemoveFace(faceId);
+  }
+
+  void
+  simulateSuccessfulResponse(const RibUpdate& update)
+  {
+    Rib::UpdateSuccessCallback managerCallback = bind(&FibUpdatesFixture::onSuccess, this);
+
+    rib.beginApplyUpdate(update, managerCallback, nullptr);
+
+    RibUpdateBatch batch(update.getRoute().faceId);
+    batch.add(update);
+
+    // Simulate a successful response from NFD
+    rib.onFibUpdateSuccess(batch, fibUpdater.m_inheritedRoutes, managerCallback);
+  }
+
+  void
+  onSuccess()
+  {
+  }
+
+  void
+  onFailure()
+  {
+    BOOST_FAIL("FibUpdate failed");
+  }
+
+  const FibUpdater::FibUpdateList&
+  getFibUpdates()
+  {
+    fibUpdates.clear();
+    fibUpdates = fibUpdater.m_updatesForBatchFaceId;
+    fibUpdates.insert(fibUpdates.end(), fibUpdater.m_updatesForNonBatchFaceId.begin(),
+                                        fibUpdater.m_updatesForNonBatchFaceId.end());
+
+    return fibUpdates;
   }
 
 
-  Rib::FibUpdateList
+  FibUpdater::FibUpdateList
   getSortedFibUpdates()
   {
-    Rib::FibUpdateList updates = rib.getFibUpdates();
+    FibUpdater::FibUpdateList updates = getFibUpdates();
     updates.sort(&compareNameFaceIdCostAction);
     return updates;
   }
 
+  void
+  clearFibUpdates()
+  {
+    fibUpdater.m_updatesForBatchFaceId.clear();
+    fibUpdater.m_updatesForNonBatchFaceId.clear();
+  }
+
 public:
+  shared_ptr<ndn::util::DummyClientFace> face;
+  ndn::KeyChain keyChain;
+  ndn::nfd::Controller controller;
+  rib::FibUpdater fibUpdater;
   rib::Rib rib;
+
+  FibUpdater::FibUpdateList fibUpdates;
 };
 
 } // namespace tests
diff --git a/tests/rib/fib-updates-erase-face.t.cpp b/tests/rib/fib-updates-erase-face.t.cpp
index 39e313d..2493668 100644
--- a/tests/rib/fib-updates-erase-face.t.cpp
+++ b/tests/rib/fib-updates-erase-face.t.cpp
@@ -43,18 +43,18 @@
   insertRoute("/a/b", 2, 0, 75, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to remove face 1 from /
   eraseRoute("/", 1, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(WithInheritedFace)
@@ -69,23 +69,23 @@
   eraseRoute("/a", 5, 255);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to remove face 3 from /a/b and one to remove inherited route
   eraseRoute("/a/b", 3, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 3);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 3);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(MultipleFaces)
@@ -94,19 +94,19 @@
   insertRoute("/a", 5, 255, 5, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to update cost to 10 for /a
   eraseRoute("/a", 5, 255);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 5);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 5);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(NoFlags_NoCaptureChange_NoCaptureOnRoute)
@@ -118,19 +118,19 @@
   insertRoute("/a", 1, 128, 50, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to update cost for /a
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(MakeRibEmpty)
@@ -138,18 +138,18 @@
   insertRoute("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to remove route from /
   eraseRoute("/", 1, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(NoFlags_NoCaptureChange_CaptureOnRoute)
@@ -161,18 +161,18 @@
   insertRoute("/a", 1, 128, 50, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to remove route from /a
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(BothFlags_NoCaptureChange_CaptureOnRoute)
@@ -185,24 +185,24 @@
                                      ndn::nfd::ROUTE_FLAG_CAPTURE));
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to remove face1 from /a and
   // 1 to remove face1 from /a/b
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(BothFlags_CaptureChange_NoCaptureOnRoute)
@@ -215,26 +215,26 @@
                                      ndn::nfd::ROUTE_FLAG_CAPTURE));
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to add face1 to /a and
   // 1 to add face1 to /a/b
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(ChildInherit_NoCaptureChange_NoCaptureOnRoute)
@@ -246,25 +246,25 @@
   insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 2 to add face1 to /a and /a/b
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(ChildInherit_NoCaptureChange_CaptureOnRoute)
@@ -276,23 +276,23 @@
   insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 2 to remove face 1 from /a and /a/b
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(Capture_CaptureChange_NoCaptureOnRoute)
@@ -304,26 +304,26 @@
   insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to update cost on /a and
   // 1 to add face1 to /a/b
   eraseRoute("/a", 1 ,128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(Capture_NoCaptureChange_CaptureOnRoute)
@@ -335,56 +335,46 @@
   insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 updates: 1 to remove route from /a
   eraseRoute("/a", 1, 128);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(EraseFaceById)
 {
   insertRoute("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
-  insertRoute("/a", 2, 0, 10, 0);
-  insertRoute("/a/b", 3, 0, 10, 0);
-  insertRoute("/a/c", 4, 0, 100, 0);
-  insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
+  insertRoute("/a", 3, 0, 10, 0);
+  insertRoute("/a/b", 4, 0, 10, 0);
+  insertRoute("/a/c", 1, 0, 100, 0);
+  insertRoute("/a", 2, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
-  // Should generate 4 updates: 4 to remove face ID 1 from /, /a, /a/b, and /a/c
-  rib.erase(1);
+  // Should generate 2 updates: 2 to add face ID 1 to /a and /a/b
+  destroyFace(2);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
-  BOOST_REQUIRE_EQUAL(updates.size(), 4);
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
+  BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
-
-  ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
-
-  ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/c");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // EraseFace
diff --git a/tests/rib/fib-updates-new-face.t.cpp b/tests/rib/fib-updates-new-face.t.cpp
index 850e8ae..49cd56f 100644
--- a/tests/rib/fib-updates-new-face.t.cpp
+++ b/tests/rib/fib-updates-new-face.t.cpp
@@ -41,18 +41,18 @@
   // should generate 1 update
   insertRoute("/", 1, 0, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = rib.getFibUpdates();
+  FibUpdater::FibUpdateList updates = getFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
 
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   // Clear any updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // should generate 2 updates
   insertRoute("/a", 2, 0, 50, 0);
@@ -61,19 +61,19 @@
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
   update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // should generate 2 updates
   insertRoute("/a/b", 3, 0, 10, 0);
@@ -82,16 +82,16 @@
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
   update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 3);
-  BOOST_CHECK_EQUAL((*update)->cost,   10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 3);
+  BOOST_CHECK_EQUAL(update->cost,   10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(UpdateOnLowerCostNoChildInherit)
@@ -99,12 +99,12 @@
   insertRoute("/", 1, 0, 50, 0);
 
   // Clear any updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 0 updates
   insertRoute("/", 1, 128, 75, 0);
 
-  BOOST_CHECK_EQUAL(rib.getFibUpdates().size(), 0);
+  BOOST_CHECK_EQUAL(getFibUpdates().size(), 0);
 }
 
 BOOST_AUTO_TEST_CASE(UpdateOnLowerCostOnly)
@@ -113,33 +113,33 @@
   insertRoute("/a", 2, 0, 10, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: to update cost for face 1 on / and /a
   insertRoute("/", 1, 0, 25, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   25);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   25);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   25);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   25);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 0 updates
   insertRoute("/", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  BOOST_CHECK_EQUAL(rib.getFibUpdates().size(), 0);
+  BOOST_CHECK_EQUAL(getFibUpdates().size(), 0);
 }
 
 BOOST_AUTO_TEST_CASE(NoCaptureChangeWithoutChildInherit)
@@ -150,20 +150,20 @@
   insertRoute("/a/c", 4, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 1 update: 1 to add face 5 to /a
   insertRoute("/a", 5, 128, 50, 0);
 
-  const Rib::FibUpdateList& updates = rib.getFibUpdates();
+  const FibUpdater::FibUpdateList& updates = getFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
 
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 5);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 5);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(NoCaptureChangeWithChildInherit)
@@ -174,26 +174,26 @@
   insertRoute("/a/c", 4, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: one for the inserted route and
   // one to add route to /a/b
   insertRoute("/a", 4, 128, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 4);
-  BOOST_CHECK_EQUAL((*update)->cost,   5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 4);
+  BOOST_CHECK_EQUAL(update->cost,   5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 4);
-  BOOST_CHECK_EQUAL((*update)->cost,   5);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 4);
+  BOOST_CHECK_EQUAL(update->cost,   5);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(CaptureTurnedOnWithoutChildInherit)
@@ -204,31 +204,31 @@
   insertRoute("/a/c", 4, 0, 10, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 3 updates:
   // - one for the inserted route for /a and
   // - two to remove face1 from /a/b and /a/c
   insertRoute("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 3);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/c");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/c");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(CaptureTurnedOnWithChildInherit)
@@ -239,7 +239,7 @@
   insertRoute("/a/c", 4, 0, 10, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates:
   // - one for the inserted route for /a and
@@ -247,20 +247,20 @@
   insertRoute("/a", 1, 128, 50, (ndn::nfd::ROUTE_FLAG_CAPTURE |
                                      ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 3);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // NewFace
diff --git a/tests/rib/fib-updates-new-namespace.t.cpp b/tests/rib/fib-updates-new-namespace.t.cpp
index e42271f..90abd31 100644
--- a/tests/rib/fib-updates-new-namespace.t.cpp
+++ b/tests/rib/fib-updates-new-namespace.t.cpp
@@ -41,25 +41,25 @@
   // No flags, empty RIB, should generate 1 update for the inserted route
   insertRoute("/a/b", 1, 0, 10, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   // Reset RIB
   eraseRoute("/a/b", 1, 0);
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Parent with child inherit flag
   insertRoute("/a", 2, 0, 70, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
   insertRoute("/a", 3, 0, 30, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 3 updates, 1 for the inserted route and 2 from inheritance
   insertRoute("/a/b", 1, 0, 10, 0);
@@ -68,22 +68,22 @@
   BOOST_REQUIRE_EQUAL(updates.size(), 3);
 
   update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->cost, 70);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->cost, 70);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 3);
-  BOOST_CHECK_EQUAL((*update)->cost, 30);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 3);
+  BOOST_CHECK_EQUAL(update->cost, 30);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(BothFlags)
@@ -91,24 +91,24 @@
   // Empty RIB, should generate 1 update for the inserted route
   insertRoute("/a", 1, 0, 10, (ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE));
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   // Reset RIB
   eraseRoute("/a", 1, 0);
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   insertRoute("/", 2, 0, 70, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
   insertRoute("/a/b", 3, 0, 30, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 3 updates, 1 for the inserted route, 1 to add the route to the child,
   // and 1 to remove the previously inherited route
@@ -118,21 +118,21 @@
   BOOST_REQUIRE_EQUAL(updates.size(), 3);
 
   update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(ChildInherit)
@@ -142,25 +142,25 @@
   insertRoute("/a/c", 3, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 for the inserted route and 1 to add the route to "/a/b"
   insertRoute("/a", 1, 0, 10, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(Capture)
@@ -170,25 +170,25 @@
   insertRoute("/a/c", 3, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 for the inserted route and
   // 1 to remove the inherited route from "/a/b"
   insertRoute("/a", 1, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // NewNamespace
diff --git a/tests/rib/fib-updates-update-face.t.cpp b/tests/rib/fib-updates-update-face.t.cpp
index af49188..54cd2d4 100644
--- a/tests/rib/fib-updates-update-face.t.cpp
+++ b/tests/rib/fib-updates-update-face.t.cpp
@@ -43,26 +43,26 @@
   insertRoute("/", 1, 128, 25, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to update the cost of / face 1 to 50 and
   // 1 to update the cost of /a face 1 to 50
   insertRoute("/", 1, 128, 75, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(UpdateOnLowerCostOnly)
@@ -72,16 +72,16 @@
   insertRoute("/", 1, 128, 100, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 0 updates
   insertRoute("/", 1, 128, 75, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates
   insertRoute("/", 1, 128, 25, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
@@ -89,17 +89,17 @@
   updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   25);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   25);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   25);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   25);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(NoChangeInCost)
@@ -110,12 +110,12 @@
   insertRoute("/a/c", 4, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 0 updates
   insertRoute("/a", 2, 0, 100, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 0);
 }
 
@@ -127,26 +127,26 @@
   insertRoute("/a/c", 4, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Should generate 2 updates: 1 to add face2 with new cost to /a and
   // 1 to add face2 with new cost to /a/b
   insertRoute("/a", 2, 0, 300, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->cost,   300);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->cost,   300);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->cost,   300);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->cost,   300);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(TurnOnChildInherit)
@@ -157,20 +157,20 @@
   insertRoute("/a/c", 4, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Turn on child inherit flag for the entry in /a
   // Should generate 1 updates: 1 to add face to /a/b
   insertRoute("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 2);
-  BOOST_CHECK_EQUAL((*update)->cost,   10);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 2);
+  BOOST_CHECK_EQUAL(update->cost,   10);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(TurnOffChildInherit)
@@ -181,20 +181,20 @@
   insertRoute("/a/c", 1, 0, 25, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Turn off child inherit flag for the entry in /a
   // Should generate 1 update: 1 to add face1 to /a/b
   insertRoute("/a", 1, 0, 100, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 1);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost,   50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost,   50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(TurnOnCapture)
@@ -205,25 +205,25 @@
   insertRoute("/a/c", 1, 0, 10, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Turn on capture flag for the entry in /a
   // Should generate 2 updates: 1 to remove face1 from /a and
   // 1 to remove face1 from /a/b
   insertRoute("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::REMOVE_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_CASE(TurnOffCapture)
@@ -234,27 +234,27 @@
   insertRoute("/a/c", 1, 0, 10, 0);
 
   // Clear updates generated from previous insertions
-  rib.clearFibUpdates();
+  clearFibUpdates();
 
   // Turn off capture flag for the entry in /a
   // Should generate 2 updates: 1 to add face1 to /a and
   // 1 to add face1 to /a/b
   insertRoute("/a", 2, 0, 10, 0);
 
-  Rib::FibUpdateList updates = getSortedFibUpdates();
+  FibUpdater::FibUpdateList updates = getSortedFibUpdates();
   BOOST_REQUIRE_EQUAL(updates.size(), 2);
 
-  Rib::FibUpdateList::const_iterator update = updates.begin();
-  BOOST_CHECK_EQUAL((*update)->name,  "/a");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  FibUpdater::FibUpdateList::const_iterator update = updates.begin();
+  BOOST_CHECK_EQUAL(update->name,  "/a");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 
   ++update;
-  BOOST_CHECK_EQUAL((*update)->name,  "/a/b");
-  BOOST_CHECK_EQUAL((*update)->faceId, 1);
-  BOOST_CHECK_EQUAL((*update)->cost, 50);
-  BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
+  BOOST_CHECK_EQUAL(update->name,  "/a/b");
+  BOOST_CHECK_EQUAL(update->faceId, 1);
+  BOOST_CHECK_EQUAL(update->cost, 50);
+  BOOST_CHECK_EQUAL(update->action, FibUpdate::ADD_NEXTHOP);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // UpdateFace
diff --git a/tests/rib/remote-registrator.t.cpp b/tests/rib/remote-registrator.t.cpp
index 5c81f88..dc41cda 100644
--- a/tests/rib/remote-registrator.t.cpp
+++ b/tests/rib/remote-registrator.t.cpp
@@ -63,32 +63,30 @@
                              bind(&RemoteRegistrator::loadConfig, remoteRegistrator, _1));
 
 
-    if (isSetRetry)
-      {
-        const std::string CONFIG_STRING =
-        "remote_register\n"
-        "{\n"
-        "  cost 15\n"
-        "  timeout 1000\n"
-        "  retry 1\n"
-        "  refresh_interval 5\n"
-        "}";
+    if (isSetRetry) {
+      const std::string CONFIG_STRING =
+      "remote_register\n"
+      "{\n"
+      "  cost 15\n"
+      "  timeout 1000\n"
+      "  retry 1\n"
+      "  refresh_interval 5\n"
+      "}";
 
-        config.parse(CONFIG_STRING, true, "test-remote-register");
-      }
-    else
-      {
-        const std::string CONFIG_STRING =
-        "remote_register\n"
-        "{\n"
-        "  cost 15\n"
-        "  timeout 100000\n"
-        "  retry 0\n"
-        "  refresh_interval 5\n"
-        "}";
+      config.parse(CONFIG_STRING, true, "test-remote-register");
+    }
+    else {
+      const std::string CONFIG_STRING =
+      "remote_register\n"
+      "{\n"
+      "  cost 15\n"
+      "  timeout 100000\n"
+      "  retry 0\n"
+      "  refresh_interval 5\n"
+      "}";
 
-        config.parse(CONFIG_STRING, true, "test-remote-register");
-      }
+      config.parse(CONFIG_STRING, true, "test-remote-register");
+    }
   }
 
   void
@@ -156,7 +154,9 @@
   void
   eraseFace(uint64_t faceId)
   {
-    rib.erase(faceId);
+    for (const Rib::NameAndRoute& item : rib.findRoutesWithFaceId(faceId)) {
+      rib.erase(item.first, item.second);
+    }
 
     advanceClocks(time::milliseconds(1));
   }
diff --git a/tests/rib/rib-manager.t.cpp b/tests/rib/rib-manager.t.cpp
index 9b31996..cfce38b 100644
--- a/tests/rib/rib-manager.t.cpp
+++ b/tests/rib/rib-manager.t.cpp
@@ -42,6 +42,8 @@
     : COMMAND_PREFIX("/localhost/nfd/rib")
     , ADD_NEXTHOP_VERB("add-nexthop")
     , REMOVE_NEXTHOP_VERB("remove-nexthop")
+    , REGISTER_COMMAND("/localhost/nfd/rib/register")
+    , UNREGISTER_COMMAND("/localhost/nfd/rib/unregister")
   {
     face = ndn::util::makeDummyClientFace();
 
@@ -58,8 +60,9 @@
     face.reset();
   }
 
-  void extractParameters(Interest& interest, Name::Component& verb,
-                         ControlParameters& extractedParameters)
+  void
+  extractParameters(Interest& interest, Name::Component& verb,
+                    ControlParameters& extractedParameters)
   {
     const Name& name = interest.getName();
     verb = name[COMMAND_PREFIX.size()];
@@ -69,19 +72,38 @@
     extractedParameters.wireDecode(rawParameters);
   }
 
-  void receiveCommandInterest(Name& name, ControlParameters& parameters)
+  void
+  receiveCommandInterest(const Name& name, ControlParameters& parameters)
   {
-    receiveCommandInterest(name.append(parameters.wireEncode()));
-  }
+    Name commandName = name;
+    commandName.append(parameters.wireEncode());
 
-  void receiveCommandInterest(const Name& name)
-  {
-    Interest command(name);
+    Interest commandInterest(commandName);
 
-    face->receive(command);
+    manager->m_managedRib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue,
+                                                        this, _1, parameters);
+
+    face->receive(commandInterest);
     face->processEvents(time::milliseconds(1));
   }
 
+  void
+  onSendBatchFromQueue(const RibUpdateBatch& batch, const ControlParameters parameters)
+  {
+    BOOST_REQUIRE(batch.begin() != batch.end());
+    RibUpdate update = *(batch.begin());
+
+    Rib::UpdateSuccessCallback managerCallback =
+      bind(&RibManager::onRibUpdateSuccess, manager, update);
+
+    Rib& rib = manager->m_managedRib;
+
+    // Simulate a successful response from NFD
+    FibUpdater& updater = manager->m_fibUpdater;
+    rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes, managerCallback);
+  }
+
+
 public:
   shared_ptr<RibManager> manager;
   shared_ptr<ndn::util::DummyClientFace> face;
@@ -89,6 +111,9 @@
   const Name COMMAND_PREFIX;
   const Name::Component ADD_NEXTHOP_VERB;
   const Name::Component REMOVE_NEXTHOP_VERB;
+
+  const Name REGISTER_COMMAND;
+  const Name UNREGISTER_COMMAND;
 };
 
 class AuthorizedRibManager : public RibManagerFixture
@@ -122,7 +147,9 @@
 BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
 {
   Name commandName("/localhost/nfd/rib");
-  receiveCommandInterest(commandName);
+  ndn::nfd::ControlParameters parameters;
+
+  receiveCommandInterest(commandName, parameters);
   // TODO verify error response
 }
 
@@ -137,9 +164,7 @@
     .setOrigin(128)
     .setExpirationPeriod(ndn::time::milliseconds::max());
 
-  Name commandName("/localhost/nfd/rib/register");
-
-  receiveCommandInterest(commandName, parameters);
+  receiveCommandInterest(REGISTER_COMMAND, parameters);
 
   BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
 }
@@ -155,9 +180,7 @@
     .setOrigin(128)
     .setExpirationPeriod(ndn::time::milliseconds::max());
 
-  Name commandName("/localhost/nfd/rib/register");
-
-  receiveCommandInterest(commandName, parameters);
+  receiveCommandInterest(REGISTER_COMMAND, parameters);
 
   BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
 
@@ -184,9 +207,7 @@
     .setOrigin(128)
     .setExpirationPeriod(ndn::time::milliseconds::max());
 
-  Name registerName("/localhost/nfd/rib/register");
-
-  receiveCommandInterest(registerName, addParameters);
+  receiveCommandInterest(REGISTER_COMMAND, addParameters);
   face->sentInterests.clear();
 
   ControlParameters removeParameters;
@@ -195,9 +216,7 @@
     .setFaceId(1)
     .setOrigin(128);
 
-  Name unregisterName("/localhost/nfd/rib/unregister");
-
-  receiveCommandInterest(unregisterName, removeParameters);
+  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
 
   BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
 
@@ -212,6 +231,7 @@
   BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
 }
 
+
 BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
 {
   ControlParameters parameters;
@@ -223,51 +243,35 @@
     .setOrigin(128)
     .setExpirationPeriod(ndn::time::milliseconds::max());
 
-  Name commandName("/localhost/nfd/rib/register");
-
   BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
 
-  receiveCommandInterest(commandName, parameters);
+  receiveCommandInterest(REGISTER_COMMAND, parameters);
 
   BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
 }
 
 BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager)
 {
+  Name prefix("/");
+
   Route route;
-  Name name("/");
   route.faceId = 1;
   route.origin = 128;
   route.cost = 32;
   route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE;
 
-  ControlParameters parameters;
-  parameters
-    .setName(name)
-    .setFaceId(route.faceId)
-    .setOrigin(route.origin)
-    .setCost(route.cost)
-    .setFlags(route.flags)
-    .setExpirationPeriod(ndn::time::milliseconds::max());
-
-  Name commandName("/localhost/nfd/rib/register");
-
-  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
-
-  receiveCommandInterest(commandName, parameters);
-  face->sentInterests.clear();
-  face->sentDatas.clear();
+  manager->m_managedRib.insert(prefix, route);
 
   face->receive(Interest("/localhost/nfd/rib/list"));
   face->processEvents(time::milliseconds(1));
 
   BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
-  RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], name, route);
+  RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
 }
 
 BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager)
 {
-  // Register face
+  // Register route
   ControlParameters addParameters;
   addParameters
     .setName("/expire")
@@ -277,26 +281,21 @@
     .setOrigin(128)
     .setExpirationPeriod(ndn::time::milliseconds(500));
 
-  Name registerName("/localhost/nfd/rib/register");
-
-  receiveCommandInterest(registerName, addParameters);
+  receiveCommandInterest(REGISTER_COMMAND, addParameters);
   face->sentInterests.clear();
 
-  // Unregister face
+  // Unregister route
   ControlParameters removeParameters;
   removeParameters
     .setName("/expire")
     .setFaceId(1)
     .setOrigin(128);
 
-  Name unregisterName("/localhost/nfd/rib/unregister");
+  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
 
-  receiveCommandInterest(unregisterName, removeParameters);
-
-  // Reregister face
-  Name reRegisterName("/localhost/nfd/rib/register");
+  // Reregister route
   addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
-  receiveCommandInterest(reRegisterName, addParameters);
+  receiveCommandInterest(REGISTER_COMMAND, addParameters);
 
   nfd::tests::LimitedIo limitedIo;
   limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
@@ -312,8 +311,7 @@
     .setName("/test")
     .setFaceId(1);
 
-  Name validName("/localhost/nfd/rib/register");
-  receiveCommandInterest(validName, validParameters);
+  receiveCommandInterest(REGISTER_COMMAND, validParameters);
 
   // Register invalid face
   ControlParameters invalidParameters;
@@ -321,8 +319,7 @@
     .setName("/test")
     .setFaceId(2);
 
-  Name invalidName("/localhost/nfd/rib/register");
-  receiveCommandInterest(invalidName, invalidParameters);
+  receiveCommandInterest(REGISTER_COMMAND, invalidParameters);
 
   BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2);
 
@@ -388,6 +385,44 @@
   BOOST_CHECK_EQUAL(routeIt->cost, 25);
 }
 
+BOOST_FIXTURE_TEST_CASE(RouteExpiration, AuthorizedRibManager)
+{
+  // Register route
+  ControlParameters parameters;
+  parameters.setName("/expire")
+            .setExpirationPeriod(ndn::time::milliseconds(500));
+
+  receiveCommandInterest(REGISTER_COMMAND, parameters);
+  face->sentInterests.clear();
+
+  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
+
+  // Route should expire
+  nfd::tests::LimitedIo limitedIo;
+  limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
+
+  BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, AuthorizedRibManager)
+{
+  uint64_t faceToDestroy = 128;
+
+  // Register valid face
+  ControlParameters parameters;
+  parameters.setName("/test")
+            .setFaceId(faceToDestroy);
+
+  receiveCommandInterest(REGISTER_COMMAND, parameters);
+  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
+
+  // Don't respond with a success message from the FIB
+  manager->m_managedRib.m_onSendBatchFromQueue = nullptr;
+
+  manager->onFaceDestroyedEvent(faceToDestroy);
+  BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 0);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace tests
diff --git a/tests/rib/rib-test-common.hpp b/tests/rib/rib-test-common.hpp
new file mode 100644
index 0000000..997b455
--- /dev/null
+++ b/tests/rib/rib-test-common.hpp
@@ -0,0 +1,46 @@
+/* -*- 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 "rib/route.hpp"
+
+namespace nfd {
+namespace rib {
+namespace tests {
+
+inline Route
+createRoute(uint64_t faceId, uint64_t origin, uint64_t cost, uint64_t flags)
+{
+  Route temp;
+  temp.faceId = faceId;
+  temp.origin = origin;
+  temp.cost = cost;
+  temp.flags = flags;
+
+  return temp;
+}
+
+} // namespace tests
+} // namespace rib
+} // namespace nfd
diff --git a/tests/rib/rib-update.cpp b/tests/rib/rib-update.cpp
new file mode 100644
index 0000000..c7b1c6c
--- /dev/null
+++ b/tests/rib/rib-update.cpp
@@ -0,0 +1,85 @@
+/* -*- 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 "tests/test-common.hpp"
+#include "rib-test-common.hpp"
+
+#include "rib/rib-update.hpp"
+#include "rib/rib-update-batch.hpp"
+
+namespace nfd {
+namespace rib {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(RibRibUpdate, nfd::tests::BaseFixture)
+
+BOOST_AUTO_TEST_CASE(BatchBasic)
+{
+  const uint64_t faceId = 1;
+
+  RibUpdateBatch batch(faceId);
+
+  Route routeRegister = createRoute(faceId, 128, 10, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
+
+  RibUpdate registerUpdate;
+  registerUpdate.setAction(RibUpdate::REGISTER)
+                .setName("/a")
+                .setRoute(routeRegister);
+
+  batch.add(registerUpdate);
+
+  BOOST_CHECK_EQUAL(batch.getFaceId(), faceId);
+
+  Route routeUnregister = createRoute(faceId, 0, 0, ndn::nfd::ROUTE_FLAG_CAPTURE);
+
+  RibUpdate unregisterUpdate;
+  unregisterUpdate.setAction(RibUpdate::UNREGISTER)
+                  .setName("/a/b")
+                  .setRoute(routeUnregister);
+
+  batch.add(unregisterUpdate);
+
+  BOOST_REQUIRE_EQUAL(batch.size(), 2);
+  RibUpdateBatch::const_iterator it = batch.begin();
+
+  BOOST_CHECK_EQUAL(it->getAction(), RibUpdate::REGISTER);
+  BOOST_CHECK_EQUAL(it->getName(), "/a");
+  BOOST_CHECK_EQUAL(it->getRoute(), routeRegister);
+
+  ++it;
+  BOOST_CHECK_EQUAL(it->getAction(), RibUpdate::UNREGISTER);
+  BOOST_CHECK_EQUAL(it->getName(), "/a/b");
+  BOOST_CHECK_EQUAL(it->getRoute(), routeUnregister);
+
+  ++it;
+  BOOST_CHECK(it == batch.end());
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace rib
+} // namespace nfd
diff --git a/tests/rib/rib.t.cpp b/tests/rib/rib.t.cpp
index 12b6208..25440dd 100644
--- a/tests/rib/rib.t.cpp
+++ b/tests/rib/rib.t.cpp
@@ -231,41 +231,6 @@
   BOOST_CHECK(ribEntry3->getParent() == ribEntry1);
 }
 
-BOOST_AUTO_TEST_CASE(EraseByFaceId)
-{
-  rib::Rib rib;
-
-  Route route1;
-  Name name1("/");
-  route1.faceId = 1;
-  route1.origin = 20;
-  rib.insert(name1, route1);
-
-  Route route2;
-  Name name2("/hello/world");
-  route2.faceId = 2;
-  route2.origin = 20;
-  rib.insert(name2, route2);
-
-  Route route3;
-  Name name3("/hello/world");
-  route3.faceId = 1;
-  route3.origin = 20;
-  rib.insert(name3, route3);
-
-  rib.erase(1);
-  BOOST_CHECK(rib.find(name1) == rib.end());
-  BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
-
-  rib.erase(3);
-  BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
-
-  rib.erase(2);
-  BOOST_CHECK(rib.find(name2) == rib.end());
-
-  rib.erase(3);
-}
-
 BOOST_AUTO_TEST_CASE(Basic)
 {
   rib::Rib rib;