diff --git a/tests/daemon/mgmt/rib-manager.t.cpp b/tests/daemon/mgmt/rib-manager.t.cpp
new file mode 100644
index 0000000..46da6a1
--- /dev/null
+++ b/tests/daemon/mgmt/rib-manager.t.cpp
@@ -0,0 +1,551 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/rib-manager.hpp"
+#include "core/fib-max-depth.hpp"
+#include "rib/fib-updater.hpp"
+
+#include "tests/manager-common-fixture.hpp"
+
+#include <ndn-cxx/lp/tags.hpp>
+#include <ndn-cxx/mgmt/nfd/face-status.hpp>
+#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>
+
+namespace nfd {
+namespace tests {
+
+struct ConfigurationStatus
+{
+  bool isLocalhostConfigured;
+  bool isLocalhopConfigured;
+};
+
+static ConfigSection
+getValidatorConfigSection()
+{
+  ConfigSection section;
+  section.put("trust-anchor.type", "any");
+  return section;
+}
+
+class RibManagerFixture : public ManagerCommonFixture
+{
+public:
+  explicit
+  RibManagerFixture(const ConfigurationStatus& status, bool shouldClearRib)
+    : m_commands(m_face.sentInterests)
+    , m_status(status)
+    , m_scheduler(g_io)
+    , m_nfdController(m_face, m_keyChain)
+    , m_fibUpdater(m_rib, m_nfdController)
+    , m_manager(m_rib, m_face, m_keyChain, m_nfdController, m_dispatcher, m_scheduler)
+  {
+    m_rib.mockFibResponse = [] (const rib::RibUpdateBatch& batch) {
+      BOOST_CHECK(batch.begin() != batch.end());
+      return true;
+    };
+    m_rib.wantMockFibResponseOnce = false;
+
+    if (m_status.isLocalhostConfigured) {
+      m_manager.applyLocalhostConfig(getValidatorConfigSection(), "test");
+    }
+    if (m_status.isLocalhopConfigured) {
+      m_manager.enableLocalhop(getValidatorConfigSection(), "test");
+    }
+    else {
+      m_manager.disableLocalhop();
+    }
+
+    registerWithNfd();
+
+    if (shouldClearRib) {
+      clearRib();
+    }
+  }
+
+private:
+  void
+  registerWithNfd()
+  {
+    m_manager.registerWithNfd();
+    advanceClocks(1_ms);
+
+    auto replyFibAddCommand = [this] (const Interest& interest) {
+      nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
+      BOOST_CHECK(params.getName() == "/localhost/nfd/rib" || params.getName() == "/localhop/nfd/rib");
+      params.setFaceId(1).setCost(0);
+      nfd::ControlResponse resp;
+
+      resp.setCode(200).setBody(params.wireEncode());
+      shared_ptr<Data> data = make_shared<Data>(interest.getName());
+      data->setContent(resp.wireEncode());
+
+      m_keyChain.sign(*data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
+
+      m_face.getIoService().post([this, data] { m_face.receive(*data); });
+    };
+
+    Name commandPrefix("/localhost/nfd/fib/add-nexthop");
+    for (const auto& command : m_commands) {
+      if (commandPrefix.isPrefixOf(command.getName())) {
+        replyFibAddCommand(command);
+        advanceClocks(1_ms);
+      }
+    }
+
+    // clear commands and responses
+    m_responses.clear();
+    m_commands.clear();
+  }
+
+  void
+  clearRib()
+  {
+    while (!m_rib.empty()) {
+      m_rib.erase(m_rib.begin()->first, *m_rib.begin()->second->begin());
+    }
+  }
+
+public:
+  static ControlParameters
+  makeRegisterParameters(const Name& name, uint64_t faceId = 0,
+                         time::milliseconds expiry = time::milliseconds::max())
+  {
+    return ControlParameters()
+      .setName(name)
+      .setFaceId(faceId)
+      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR)
+      .setCost(10)
+      .setFlags(0)
+      .setExpirationPeriod(expiry);
+  }
+
+  static ControlParameters
+  makeUnregisterParameters(const Name& name, uint64_t faceId = 0)
+  {
+    return ControlParameters()
+      .setName(name)
+      .setFaceId(faceId)
+      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR);
+  }
+
+public:
+  enum class CheckCommandResult {
+    OK,
+    OUT_OF_BOUNDARY,
+    WRONG_FORMAT,
+    WRONG_VERB,
+    WRONG_PARAMS_FORMAT,
+    WRONG_PARAMS_NAME,
+    WRONG_PARAMS_FACE
+  };
+
+  CheckCommandResult
+  checkCommand(size_t idx, const char* verbStr, const ControlParameters& expectedParams) const
+  {
+    if (idx > m_commands.size()) {
+      return CheckCommandResult::OUT_OF_BOUNDARY;
+    }
+    const auto& name = m_commands[idx].getName();
+
+    if (!FIB_COMMAND_PREFIX.isPrefixOf(name) || FIB_COMMAND_PREFIX.size() >= name.size()) {
+      return CheckCommandResult::WRONG_FORMAT;
+    }
+    const auto& verb = name[FIB_COMMAND_PREFIX.size()];
+
+    Name::Component expectedVerb(verbStr);
+    if (verb != expectedVerb) {
+      return CheckCommandResult::WRONG_VERB;
+    }
+
+    ControlParameters parameters;
+    try {
+      Block rawParameters = name[FIB_COMMAND_PREFIX.size() + 1].blockFromValue();
+      parameters.wireDecode(rawParameters);
+    }
+    catch (...) {
+      return CheckCommandResult::WRONG_PARAMS_FORMAT;
+    }
+
+    if (parameters.getName() != expectedParams.getName()) {
+      return CheckCommandResult::WRONG_PARAMS_NAME;
+    }
+
+    if (parameters.getFaceId() != expectedParams.getFaceId()) {
+      return CheckCommandResult::WRONG_PARAMS_FACE;
+    }
+
+    return CheckCommandResult::OK;
+  }
+
+protected:
+  static const Name FIB_COMMAND_PREFIX;
+  std::vector<Interest>& m_commands;
+  ConfigurationStatus m_status;
+
+  ndn::util::Scheduler m_scheduler;
+  ndn::nfd::Controller m_nfdController;
+  rib::Rib m_rib;
+  rib::FibUpdater m_fibUpdater;
+  RibManager m_manager;
+};
+
+const Name RibManagerFixture::FIB_COMMAND_PREFIX("/localhost/nfd/fib");
+
+std::ostream&
+operator<<(std::ostream& os, RibManagerFixture::CheckCommandResult result)
+{
+  switch (result) {
+  case RibManagerFixture::CheckCommandResult::OK:
+    return os << "OK";
+  case RibManagerFixture::CheckCommandResult::OUT_OF_BOUNDARY:
+    return os << "OUT_OF_BOUNDARY";
+  case RibManagerFixture::CheckCommandResult::WRONG_FORMAT:
+    return os << "WRONG_FORMAT";
+  case RibManagerFixture::CheckCommandResult::WRONG_VERB:
+    return os << "WRONG_VERB";
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FORMAT:
+    return os << "WRONG_PARAMS_FORMAT";
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_NAME:
+    return os << "WRONG_PARAMS_NAME";
+  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FACE:
+    return os << "WRONG_PARAMS_FACE";
+  };
+
+  return os << static_cast<int>(result);
+}
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestRibManager)
+
+class AddTopPrefixFixture : public RibManagerFixture
+{
+public:
+  AddTopPrefixFixture()
+    : RibManagerFixture({true, true}, false)
+  {
+  }
+};
+
+BOOST_FIXTURE_TEST_CASE(AddTopPrefix, AddTopPrefixFixture)
+{
+  BOOST_CHECK_EQUAL(m_rib.size(), 2);
+
+  std::vector<Name> ribEntryNames;
+  for (auto&& entry : m_rib) {
+    ribEntryNames.push_back(entry.first);
+  }
+  BOOST_CHECK_EQUAL(ribEntryNames[0], "/localhop/nfd");
+  BOOST_CHECK_EQUAL(ribEntryNames[1], "/localhost/nfd");
+}
+
+class UnauthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  UnauthorizedRibManagerFixture()
+    : RibManagerFixture({false, false}, true)
+  {
+  }
+};
+
+class LocalhostAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  LocalhostAuthorizedRibManagerFixture()
+    : RibManagerFixture({true, false}, true)
+  {
+  }
+};
+
+class LocalhopAuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  LocalhopAuthorizedRibManagerFixture()
+    : RibManagerFixture({false, true}, true)
+  {
+  }
+};
+
+class AuthorizedRibManagerFixture : public RibManagerFixture
+{
+public:
+  AuthorizedRibManagerFixture()
+    : RibManagerFixture({true, true}, true)
+  {
+  }
+};
+
+using AllFixtures = boost::mpl::vector<
+  UnauthorizedRibManagerFixture,
+  LocalhostAuthorizedRibManagerFixture,
+  LocalhopAuthorizedRibManagerFixture,
+  AuthorizedRibManagerFixture
+>;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(CommandAuthorization, T, AllFixtures, T)
+{
+  auto parameters  = this->makeRegisterParameters("/test-authorization", 9527);
+  auto commandHost = this->makeControlCommandRequest("/localhost/nfd/rib/register", parameters);
+  auto commandHop  = this->makeControlCommandRequest("/localhop/nfd/rib/register", parameters);
+  auto successResp = this->makeResponse(200, "Success", parameters);
+  auto failureResp = ControlResponse(403, "authorization rejected");
+
+  BOOST_CHECK_EQUAL(this->m_responses.size(), 0);
+  this->receiveInterest(commandHost);
+  this->receiveInterest(commandHop);
+
+  auto nExpectedResponses = this->m_status.isLocalhopConfigured ? 2 : 1;
+  auto expectedLocalhostResponse = this->m_status.isLocalhostConfigured ? successResp : failureResp;
+  auto expectedLocalhopResponse = this->m_status.isLocalhopConfigured ? successResp : failureResp;
+
+  BOOST_REQUIRE_EQUAL(this->m_responses.size(), nExpectedResponses);
+  BOOST_CHECK_EQUAL(this->checkResponse(0, commandHost.getName(), expectedLocalhostResponse),
+                    ManagerCommonFixture::CheckResponseResult::OK);
+  if (nExpectedResponses == 2) {
+    BOOST_CHECK_EQUAL(this->checkResponse(1, commandHop.getName(), expectedLocalhopResponse),
+                      ManagerCommonFixture::CheckResponseResult::OK);
+  }
+}
+
+BOOST_FIXTURE_TEST_SUITE(RegisterUnregister, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  auto paramsRegister    = makeRegisterParameters("/test-register-unregister", 9527);
+  auto paramsUnregister  = makeUnregisterParameters("/test-register-unregister", 9527);
+
+  auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister);
+  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));
+  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister);
+  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));
+
+  receiveInterest(commandRegister);
+  receiveInterest(commandUnregister);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "Success", paramsRegister)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "Success", paramsUnregister)),
+                    CheckResponseResult::OK);
+
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(SelfOperation)
+{
+  auto paramsRegister = makeRegisterParameters("/test-self-register-unregister");
+  auto paramsUnregister = makeUnregisterParameters("/test-self-register-unregister");
+  BOOST_CHECK_EQUAL(paramsRegister.getFaceId(), 0);
+  BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);
+
+  const uint64_t inFaceId = 9527;
+  auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister);
+  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
+  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister);
+  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
+
+  receiveInterest(commandRegister);
+  receiveInterest(commandUnregister);
+
+  paramsRegister.setFaceId(inFaceId);
+  paramsUnregister.setFaceId(inFaceId);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "Success", paramsRegister)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "Success", paramsUnregister)),
+                    CheckResponseResult::OK);
+
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(Expiration)
+{
+  auto paramsRegister = makeRegisterParameters("/test-expiry", 9527, 50_ms);
+  auto paramsUnregister = makeRegisterParameters("/test-expiry", 9527);
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
+
+  advanceClocks(55_ms);
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2); // the registered route has expired
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
+
+  m_commands.clear();
+  paramsRegister.setExpirationPeriod(100_ms);
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));
+
+  advanceClocks(55_ms);
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 1); // the registered route is still active
+  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(NameTooLong)
+{
+  Name prefix;
+  while (prefix.size() <= FIB_MAX_DEPTH) {
+    prefix.append("A");
+  }
+  auto params = makeRegisterParameters(prefix, 2899);
+  auto command = makeControlCommandRequest("/localhost/nfd/rib/register", params);
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command.getName(), ControlResponse(414,
+                      "Route prefix cannot exceed " + ndn::to_string(FIB_MAX_DEPTH) +
+                      " components")),
+                    CheckResponseResult::OK);
+
+  BOOST_CHECK_EQUAL(m_commands.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // RegisterUnregister
+
+BOOST_FIXTURE_TEST_CASE(RibDataset, UnauthorizedRibManagerFixture)
+{
+  uint64_t faceId = 0;
+  auto generateRoute = [&faceId] () -> rib::Route {
+    rib::Route route;
+    route.faceId = ++faceId;
+    route.cost = route.faceId * 10;
+    route.expires = nullopt;
+    return route;
+  };
+
+  const size_t nEntries = 108;
+  std::set<Name> actualPrefixes;
+  for (size_t i = 0; i < nEntries; ++i) {
+    Name prefix = Name("/test-dataset").appendNumber(i);
+    actualPrefixes.insert(prefix);
+    m_rib.insert(prefix, generateRoute());
+    if (i & 0x1) {
+      m_rib.insert(prefix, generateRoute());
+      m_rib.insert(prefix, generateRoute());
+    }
+  }
+
+  receiveInterest(Interest("/localhost/nfd/rib/list"));
+
+  Block content = concatenateResponses();
+  content.parse();
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  std::vector<ndn::nfd::RibEntry> receivedRecords, expectedRecords;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    ndn::nfd::RibEntry decodedEntry(content.elements()[idx]);
+    receivedRecords.push_back(decodedEntry);
+    actualPrefixes.erase(decodedEntry.getName());
+
+    auto matchedEntryIt = m_rib.find(decodedEntry.getName());
+    BOOST_REQUIRE(matchedEntryIt != m_rib.end());
+
+    auto matchedEntry = matchedEntryIt->second;
+    BOOST_REQUIRE(matchedEntry != nullptr);
+
+    expectedRecords.emplace_back();
+    expectedRecords.back().setName(matchedEntry->getName());
+    for (const auto& route : matchedEntry->getRoutes()) {
+      expectedRecords.back().addRoute(ndn::nfd::Route()
+                                      .setFaceId(route.faceId)
+                                      .setOrigin(route.origin)
+                                      .setCost(route.cost)
+                                      .setFlags(route.flags));
+    }
+  }
+
+  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+                                expectedRecords.begin(), expectedRecords.end());
+}
+
+BOOST_FIXTURE_TEST_SUITE(FaceMonitor, LocalhostAuthorizedRibManagerFixture)
+
+BOOST_AUTO_TEST_CASE(FetchActiveFacesEvent)
+{
+  BOOST_CHECK_EQUAL(m_commands.size(), 0);
+
+  advanceClocks(301_s); // RibManager::ACTIVE_FACE_FETCH_INTERVAL = 300s
+  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
+  BOOST_CHECK_EQUAL(m_commands[0].getName(), "/localhost/nfd/faces/events");
+  BOOST_CHECK_EQUAL(m_commands[1].getName(), "/localhost/nfd/faces/list");
+}
+
+BOOST_AUTO_TEST_CASE(RemoveInvalidFaces)
+{
+  auto parameters1 = makeRegisterParameters("/test-remove-invalid-faces-1");
+  auto parameters2 = makeRegisterParameters("/test-remove-invalid-faces-2");
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(1)));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(2)));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2.setFaceId(2)));
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 3);
+
+  ndn::nfd::FaceStatus status;
+  status.setFaceId(1);
+  std::vector<ndn::nfd::FaceStatus> activeFaces;
+  activeFaces.push_back(status);
+
+  m_manager.removeInvalidFaces(activeFaces);
+  advanceClocks(100_ms);
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 1);
+
+  auto it1 = m_rib.find("/test-remove-invalid-faces-1");
+  auto it2 = m_rib.find("/test-remove-invalid-faces-2");
+  BOOST_CHECK(it2 == m_rib.end());
+  BOOST_REQUIRE(it1 != m_rib.end());
+  BOOST_CHECK(it1->second->hasFaceId(1));
+  BOOST_CHECK(!it1->second->hasFaceId(2));
+}
+
+BOOST_AUTO_TEST_CASE(OnNotification)
+{
+  auto parameters1 = makeRegisterParameters("/test-face-event-notification-1", 1);
+  auto parameters2 = makeRegisterParameters("/test-face-event-notification-2", 1);
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1));
+  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2));
+  BOOST_REQUIRE_EQUAL(m_rib.size(), 2);
+
+  auto makeNotification = [] (ndn::nfd::FaceEventKind kind, uint64_t faceId) {
+    return ndn::nfd::FaceEventNotification().setKind(kind).setFaceId(faceId);
+  };
+
+  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_DESTROYED, 1));
+  advanceClocks(100_ms);
+  BOOST_CHECK_EQUAL(m_rib.size(), 0);
+
+  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_CREATED, 2));
+  advanceClocks(100_ms);
+  BOOST_CHECK_EQUAL(m_rib.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // FaceMonitor
+
+BOOST_AUTO_TEST_SUITE_END() // TestRibManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
