rib: move config parsing to Service class

This commit also de-duplicates code in Service class constructors
and reduces usage of unique_ptrs.

refs #4650

Change-Id: Ibbf454841b76ffe4d569b51fef3b1d06f7d2fdfc
diff --git a/daemon/main.cpp b/daemon/main.cpp
index 056d359..448b105 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -128,7 +128,6 @@
           ndn::KeyChain ribKeyChain;
           // must be created inside a separate thread
           rib::Service ribService(configFile, ribKeyChain);
-          ribService.initialize();
           getGlobalIoService().run(); // ribIo is not thread-safe to use here
         }
         catch (const std::exception& e) {
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index c45aede..1d9873b 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -41,27 +41,20 @@
 
 NFD_LOG_INIT(RibManager);
 
-const Name RibManager::LOCAL_HOST_TOP_PREFIX = "/localhost/nfd";
-const Name RibManager::LOCAL_HOP_TOP_PREFIX = "/localhop/nfd";
-const std::string RibManager::MGMT_MODULE_NAME = "rib";
-const Name RibManager::FACES_LIST_DATASET_PREFIX = "/localhost/nfd/faces/list";
-const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
+static const std::string MGMT_MODULE_NAME = "rib";
+static const Name LOCALHOST_TOP_PREFIX = "/localhost/nfd";
+static const Name LOCALHOP_TOP_PREFIX = "/localhop/nfd";
+static const time::seconds ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
 
-RibManager::RibManager(Rib& rib,
-                       Dispatcher& dispatcher,
-                       ndn::Face& face,
-                       ndn::nfd::Controller& controller,
-                       AutoPrefixPropagator& propagator)
+RibManager::RibManager(Rib& rib, ndn::Face& face, ndn::nfd::Controller& nfdController, Dispatcher& dispatcher)
   : ManagerBase(dispatcher, MGMT_MODULE_NAME)
   , m_rib(rib)
-  , m_nfdController(controller)
+  , m_nfdController(nfdController)
+  , m_dispatcher(dispatcher)
   , m_faceMonitor(face)
   , m_localhostValidator(face)
   , m_localhopValidator(face)
-  , m_prefixPropagator(propagator)
-  , m_addTopPrefix([&dispatcher] (const Name& topPrefix) {
-      dispatcher.addTopPrefix(topPrefix, false);
-    })
+  , m_isLocalhopEnabled(false)
 {
   registerCommandHandler<ndn::nfd::RibRegisterCommand>("register",
     bind(&RibManager::registerEntry, this, _2, _3, _4, _5));
@@ -71,15 +64,32 @@
   registerStatusDatasetHandler("list", bind(&RibManager::listEntries, this, _1, _2, _3));
 }
 
-RibManager::~RibManager() = default;
+void
+RibManager::applyLocalhostConfig(const ConfigSection& section, const std::string& filename)
+{
+  m_localhostValidator.load(section, filename);
+}
+
+void
+RibManager::enableLocalhop(const ConfigSection& section, const std::string& filename)
+{
+  m_localhopValidator.load(section, filename);
+  m_isLocalhopEnabled = true;
+}
+
+void
+RibManager::disableLocalhop()
+{
+  m_isLocalhopEnabled = false;
+}
 
 void
 RibManager::registerWithNfd()
 {
-  registerTopPrefix(LOCAL_HOST_TOP_PREFIX);
+  registerTopPrefix(LOCALHOST_TOP_PREFIX);
 
   if (m_isLocalhopEnabled) {
-    registerTopPrefix(LOCAL_HOP_TOP_PREFIX);
+    registerTopPrefix(LOCALHOP_TOP_PREFIX);
   }
 
   NFD_LOG_INFO("Start monitoring face create/destroy events");
@@ -100,13 +110,6 @@
 }
 
 void
-RibManager::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("rib",
-                               bind(&RibManager::onConfig, this, _1, _2, _3));
-}
-
-void
 RibManager::onRibUpdateSuccess(const RibUpdate& update)
 {
   NFD_LOG_DEBUG("RIB update succeeded for " << update);
@@ -123,33 +126,6 @@
 }
 
 void
-RibManager::onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename)
-{
-  wantAutoPrefixPropagator = false;
-  wantReadvertiseToNlsr = false;
-
-  for (const auto& item : configSection) {
-    if (item.first == "localhost_security") {
-      m_localhostValidator.load(item.second, filename);
-    }
-    else if (item.first == "localhop_security") {
-      m_localhopValidator.load(item.second, filename);
-      m_isLocalhopEnabled = true;
-    }
-    else if (item.first == "auto_prefix_propagate") {
-      m_prefixPropagator.loadConfig(item.second);
-      wantAutoPrefixPropagator = true;
-    }
-    else if (item.first == "readvertise_nlsr") {
-      wantReadvertiseToNlsr = ConfigFile::parseYesNo(item, "rib.readvertise_nlsr");
-    }
-    else {
-      BOOST_THROW_EXCEPTION(Error("Unrecognized rib property: " + item.first));
-    }
-  }
-}
-
-void
 RibManager::registerTopPrefix(const Name& topPrefix)
 {
   // register entry to the FIB
@@ -161,7 +137,7 @@
     [=] (const auto& res) { this->onCommandPrefixAddNextHopError(topPrefix, res); });
 
   // add top prefix to the dispatcher
-  m_addTopPrefix(topPrefix);
+  m_dispatcher.addTopPrefix(topPrefix, false);
 }
 
 void
@@ -295,9 +271,9 @@
                  const ndn::mgmt::RejectContinuation& reject) {
     BOOST_ASSERT(params != nullptr);
     BOOST_ASSERT(typeid(*params) == typeid(ndn::nfd::ControlParameters));
-    BOOST_ASSERT(prefix == LOCAL_HOST_TOP_PREFIX || prefix == LOCAL_HOP_TOP_PREFIX);
+    BOOST_ASSERT(prefix == LOCALHOST_TOP_PREFIX || prefix == LOCALHOP_TOP_PREFIX);
 
-    ndn::ValidatorConfig& validator = prefix == LOCAL_HOST_TOP_PREFIX ?
+    ndn::ValidatorConfig& validator = prefix == LOCALHOST_TOP_PREFIX ?
                                       m_localhostValidator : m_localhopValidator;
     validator.validate(interest,
                        bind([&interest, this, accept] { extractRequester(interest, accept); }),
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index be13c44..6ef6d6b 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -42,37 +42,52 @@
 namespace nfd {
 namespace rib {
 
-class AutoPrefixPropagator;
-class Readvertise;
-
+/**
+ * @brief Serve commands and datasets in NFD RIB management protocol.
+ */
 class RibManager : public nfd::ManagerBase
 {
 public:
   class Error : public std::runtime_error
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
+    using std::runtime_error::runtime_error;
   };
 
-public:
-  RibManager(Rib& rib, Dispatcher& dispatcher, ndn::Face& face,
-             ndn::nfd::Controller& controller, AutoPrefixPropagator& propagator);
+  RibManager(Rib& rib, ndn::Face& face, ndn::nfd::Controller& nfdController, Dispatcher& dispatcher);
 
-  ~RibManager() override;
+  /**
+   * @brief Apply localhost_security configuration.
+   */
+  void
+  applyLocalhostConfig(const ConfigSection& section, const std::string& filename);
 
+  /**
+   * @brief Apply localhop_security configuration and allow accepting commands on
+   *        /localhop/nfd/rib prefix.
+   */
+  void
+  enableLocalhop(const ConfigSection& section, const std::string& filename);
+
+  /**
+   * @brief Disallow accepting commands on /localhop/nfd/rib prefix.
+   */
+  void
+  disableLocalhop();
+
+  /**
+   * @brief Start accepting commands and dataset requests.
+   */
   void
   registerWithNfd();
 
+  /**
+   * @brief Enable NDNLP IncomingFaceId field in order to support self-registration commands.
+   */
   void
   enableLocalFields();
 
-  void
-  setConfigFile(ConfigFile& configFile);
-
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   void
   onRibUpdateSuccess(const RibUpdate& update);
 
@@ -81,9 +96,6 @@
 
 private: // initialization helpers
   void
-  onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
-
-  void
   registerTopPrefix(const Name& topPrefix);
 
 private: // ControlCommand and StatusDataset
@@ -150,33 +162,23 @@
   void
   onEnableLocalFieldsError(const ControlResponse& response);
 
-public:
-  bool wantAutoPrefixPropagator = false;
-  bool wantReadvertiseToNlsr = false;
-
 private:
   Rib& m_rib;
   ndn::nfd::Controller& m_nfdController;
+  Dispatcher& m_dispatcher;
+
   ndn::nfd::FaceMonitor m_faceMonitor;
   ndn::ValidatorConfig m_localhostValidator;
   ndn::ValidatorConfig m_localhopValidator;
-  bool m_isLocalhopEnabled = false;
-  AutoPrefixPropagator& m_prefixPropagator;
+  bool m_isLocalhopEnabled;
 
 private:
-  static const Name LOCAL_HOST_TOP_PREFIX;
-  static const Name LOCAL_HOP_TOP_PREFIX;
-  static const std::string MGMT_MODULE_NAME;
-  static const Name FACES_LIST_DATASET_PREFIX;
-  static const time::seconds ACTIVE_FACE_FETCH_INTERVAL;
   scheduler::ScopedEventId m_activeFaceFetchEvent;
 
   typedef std::set<uint64_t> FaceIdSet;
   /** \brief contains FaceIds with one or more Routes in the RIB
   */
   FaceIdSet m_registeredFaces;
-
-  std::function<void(const Name& topPrefix)> m_addTopPrefix;
 };
 
 } // namespace rib
diff --git a/rib/service.cpp b/rib/service.cpp
index 739883c..ddf13ed 100644
--- a/rib/service.cpp
+++ b/rib/service.cpp
@@ -27,42 +27,89 @@
 
 #include "auto-prefix-propagator.hpp"
 #include "fib-updater.hpp"
-#include "rib-manager.hpp"
 #include "readvertise/client-to-nlsr-readvertise-policy.hpp"
 #include "readvertise/nfd-rib-readvertise-destination.hpp"
 #include "readvertise/readvertise.hpp"
 
 #include "core/global-io.hpp"
+#include "core/logger.hpp"
 
 #include <boost/property_tree/info_parser.hpp>
-
 #include <ndn-cxx/transport/tcp-transport.hpp>
 #include <ndn-cxx/transport/unix-transport.hpp>
 
 namespace nfd {
 namespace rib {
 
-static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
-static const Name READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
+NFD_LOG_INIT(RibService);
 
 Service* Service::s_instance = nullptr;
 
-Service::Service(const std::string& configFile, ndn::KeyChain& keyChain)
-  : m_configFile(configFile)
-  , m_keyChain(keyChain)
+static const std::string CFG_SECTION = "rib";
+static const std::string CFG_LOCALHOST_SECURITY = "localhost_security";
+static const std::string CFG_LOCALHOP_SECURITY = "localhop_security";
+static const std::string CFG_PREFIX_PROPAGATE = "auto_prefix_propagate";
+static const std::string CFG_READVERTISE_NLSR = "readvertise_nlsr";
+static const Name READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
+
+static ConfigSection
+loadConfigSectionFromFile(const std::string& filename)
 {
-  if (s_instance != nullptr) {
-    BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
+  ConfigSection config;
+  // Any format errors should have been caught already
+  boost::property_tree::read_info(filename, config);
+  return config;
+}
+
+/**
+ * \brief Look into the config file and construct appropriate transport to communicate with NFD
+ * If NFD-RIB instance was initialized with config file, INFO format is assumed
+ */
+static shared_ptr<ndn::Transport>
+makeLocalNfdTransport(const ConfigSection& config)
+{
+  if (config.get_child_optional("face_system.unix")) {
+    // default socket path should be the same as in UnixStreamFactory::processConfig
+    auto path = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
+    return make_shared<ndn::UnixTransport>(path);
   }
-  if (&getGlobalIoService() != &getRibIoService()) {
-    BOOST_THROW_EXCEPTION(std::logic_error("RIB service must run on RIB thread"));
+  else if (config.get_child_optional("face_system.tcp") &&
+           config.get<std::string>("face_system.tcp.listen", "yes") == "yes") {
+    // default port should be the same as in TcpFactory::processConfig
+    auto port = config.get<std::string>("face_system.tcp.port", "6363");
+    return make_shared<ndn::TcpTransport>("localhost", port);
   }
-  s_instance = this;
+  else {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("No transport is available to communicate with NFD"));
+  }
+}
+
+Service::Service(const std::string& configFile, ndn::KeyChain& keyChain)
+  : Service(keyChain, makeLocalNfdTransport(loadConfigSectionFromFile(configFile)))
+{
+  ConfigFile config(ConfigFile::ignoreUnknownSection);
+  config.addSectionHandler(CFG_SECTION, bind(&Service::processConfig, this, _1, _2, _3));
+  config.parse(configFile, true);
+  config.parse(configFile, false);
 }
 
 Service::Service(const ConfigSection& configSection, ndn::KeyChain& keyChain)
-  : m_configSection(configSection)
-  , m_keyChain(keyChain)
+  : Service(keyChain, makeLocalNfdTransport(configSection))
+{
+  ConfigFile config(ConfigFile::ignoreUnknownSection);
+  config.addSectionHandler(CFG_SECTION, bind(&Service::processConfig, this, _1, _2, _3));
+  const std::string INTERNAL_CONFIG = "internal://nfd.conf";
+  config.parse(configSection, true, INTERNAL_CONFIG);
+  config.parse(configSection, false, INTERNAL_CONFIG);
+}
+
+Service::Service(ndn::KeyChain& keyChain, shared_ptr<ndn::Transport> localNfdTransport)
+  : m_keyChain(keyChain)
+  , m_face(std::move(localNfdTransport), getGlobalIoService(), m_keyChain)
+  , m_nfdController(m_face, m_keyChain)
+  , m_fibUpdater(m_rib, m_nfdController)
+  , m_dispatcher(m_face, m_keyChain)
+  , m_ribManager(m_rib, m_face, m_nfdController, m_dispatcher)
 {
   if (s_instance != nullptr) {
     BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
@@ -91,90 +138,90 @@
 }
 
 void
-Service::initialize()
+Service::processConfig(const ConfigSection& section, bool isDryRun, const std::string& filename)
 {
-  m_face = make_unique<ndn::Face>(getLocalNfdTransport(), getGlobalIoService(), m_keyChain);
-  m_nfdController = make_unique<ndn::nfd::Controller>(*m_face, m_keyChain);
-  m_fibUpdater = make_unique<FibUpdater>(m_rib, *m_nfdController);
-  m_prefixPropagator = make_unique<AutoPrefixPropagator>(*m_nfdController, m_keyChain, m_rib);
-  m_dispatcher = make_unique<ndn::mgmt::Dispatcher>(*m_face, m_keyChain);
-  m_ribManager = make_unique<RibManager>(m_rib, *m_dispatcher, *m_face, *m_nfdController, *m_prefixPropagator);
+  if (isDryRun) {
+    checkConfig(section, filename);
+  }
+  else {
+    applyConfig(section, filename);
+  }
+}
 
-  ConfigFile config([] (const std::string& filename, const std::string& sectionName,
-                        const ConfigSection& section, bool isDryRun) {
-      // Ignore sections belonging to NFD, but raise an error
-      // if we're missing a handler for a "rib" section.
-      if (sectionName == "rib") {
-        ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
+void
+Service::checkConfig(const ConfigSection& section, const std::string& filename)
+{
+  for (const auto& item : section) {
+    const std::string& key = item.first;
+    if (key == CFG_LOCALHOST_SECURITY || key == CFG_LOCALHOP_SECURITY) {
+      ndn::security::v2::validator_config::ValidationPolicyConfig policy;
+      policy.load(section, filename);
+    }
+    else if (key == CFG_PREFIX_PROPAGATE) {
+      // AutoPrefixPropagator does not support config dry-run
+    }
+    else if (key == CFG_READVERTISE_NLSR) {
+      ConfigFile::parseYesNo(item, CFG_SECTION + "." + CFG_READVERTISE_NLSR);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option " + CFG_SECTION + "." + key));
+    }
+  }
+}
+
+void
+Service::applyConfig(const ConfigSection& section, const std::string& filename)
+{
+  bool wantPrefixPropagate = false;
+  bool wantReadvertiseNlsr = false;
+
+  for (const auto& item : section) {
+    const std::string& key = item.first;
+    const ConfigSection& value = item.second;
+    if (key == CFG_LOCALHOST_SECURITY) {
+      m_ribManager.applyLocalhostConfig(value, filename);
+    }
+    else if (key == CFG_LOCALHOP_SECURITY) {
+      m_ribManager.enableLocalhop(value, filename);
+    }
+    else if (key == CFG_PREFIX_PROPAGATE) {
+      if (m_prefixPropagator == nullptr) {
+        m_prefixPropagator = make_unique<AutoPrefixPropagator>(m_nfdController, m_keyChain, m_rib);
       }
-    });
-  m_ribManager->setConfigFile(config);
-
-  // parse config file
-  if (!m_configFile.empty()) {
-    config.parse(m_configFile, true);
-    config.parse(m_configFile, false);
-  }
-  else {
-    config.parse(m_configSection, true, INTERNAL_CONFIG);
-    config.parse(m_configSection, false, INTERNAL_CONFIG);
+      m_prefixPropagator->loadConfig(item.second);
+      m_prefixPropagator->enable();
+      wantPrefixPropagate = true;
+    }
+    else if (key == CFG_READVERTISE_NLSR) {
+      wantReadvertiseNlsr = ConfigFile::parseYesNo(item, CFG_SECTION + "." + CFG_READVERTISE_NLSR);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option " + CFG_SECTION + "." + key));
+    }
   }
 
-  if (m_ribManager->wantAutoPrefixPropagator) {
-    m_prefixPropagator->enable();
-  }
-  else {
+  if (!wantPrefixPropagate && m_prefixPropagator != nullptr) {
     m_prefixPropagator->disable();
   }
 
-  if (m_ribManager->wantReadvertiseToNlsr && m_readvertiseNlsr == nullptr) {
+  if (wantReadvertiseNlsr && m_readvertiseNlsr == nullptr) {
+    NFD_LOG_DEBUG("Enabling readvertise-to-nlsr");
     m_readvertiseNlsr = make_unique<Readvertise>(
       m_rib,
       make_unique<ClientToNlsrReadvertisePolicy>(),
-      make_unique<NfdRibReadvertiseDestination>(*m_nfdController, READVERTISE_NLSR_PREFIX, m_rib));
+      make_unique<NfdRibReadvertiseDestination>(m_nfdController, READVERTISE_NLSR_PREFIX, m_rib));
   }
-  else if (!m_ribManager->wantReadvertiseToNlsr && m_readvertiseNlsr != nullptr) {
+  else if (!wantReadvertiseNlsr && m_readvertiseNlsr != nullptr) {
+    NFD_LOG_DEBUG("Disabling readvertise-to-nlsr");
     m_readvertiseNlsr.reset();
   }
-
-  m_ribManager->registerWithNfd();
-  m_ribManager->enableLocalFields();
 }
 
-shared_ptr<ndn::Transport>
-Service::getLocalNfdTransport()
+void
+Service::initialize()
 {
-  ConfigSection config;
-
-  if (!m_configFile.empty()) {
-    // Any format errors should have been caught already
-    // If error is thrown at this point, it is development error
-    boost::property_tree::read_info(m_configFile, config);
-  }
-  else {
-    config = m_configSection;
-  }
-
-  if (config.get_child_optional("face_system.unix")) {
-    // unix socket enabled
-
-    auto socketPath = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
-    // default socketPath should be the same as in UnixStreamFactory::processConfig
-
-    return make_shared<ndn::UnixTransport>(socketPath);
-  }
-  else if (config.get_child_optional("face_system.tcp") &&
-           config.get<std::string>("face_system.tcp.listen", "yes") == "yes") {
-    // tcp is enabled
-
-    auto port = config.get<std::string>("face_system.tcp.port", "6363");
-    // default port should be the same as in TcpFactory::processConfig
-
-    return make_shared<ndn::TcpTransport>("localhost", port);
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("No transport is available to communicate with NFD"));
-  }
+  m_ribManager.registerWithNfd();
+  m_ribManager.enableLocalFields();
 }
 
 } // namespace rib
diff --git a/rib/service.hpp b/rib/service.hpp
index a32d996..b39f5c6 100644
--- a/rib/service.hpp
+++ b/rib/service.hpp
@@ -26,7 +26,8 @@
 #ifndef NFD_RIB_SERVICE_HPP
 #define NFD_RIB_SERVICE_HPP
 
-#include "rib.hpp"
+#include "rib-manager.hpp"
+
 #include "core/config-file.hpp"
 
 #include <ndn-cxx/face.hpp>
@@ -39,28 +40,17 @@
 namespace rib {
 
 class AutoPrefixPropagator;
-class FibUpdater;
 class Readvertise;
-class RibManager;
 
 /**
  * \brief initializes and executes NFD-RIB service thread
  *
- * Only one instance of this class can be created at any time
+ * Only one instance of this class can be created at any time.
+ * After initialization, NFD-RIB instance can be started by running the global io_service.
  */
 class Service : noncopyable
 {
 public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
   /**
    * \brief create NFD-RIB service
    * \param configFile absolute or relative path of configuration file
@@ -88,14 +78,6 @@
   ~Service();
 
   /**
-   * \brief Perform initialization of NFD-RIB instance
-   *
-   * After initialization, NFD-RIB instance can be started by running the global io_service
-   */
-  void
-  initialize();
-
-  /**
    * \brief Get a reference to the only instance of this class
    * \throw std::logic_error No instance has been constructed
    * \throw std::logic_error This function is invoked on a thread other than the RIB thread
@@ -104,29 +86,33 @@
   get();
 
 private:
-  /**
-   * \brief Look into the config file and construct appropriate transport to communicate with NFD
-   * If NFD-RIB instance was initialized with config file, INFO format is assumed
-   */
-  shared_ptr<ndn::Transport>
-  getLocalNfdTransport();
+  Service(ndn::KeyChain& keyChain, shared_ptr<ndn::Transport> localNfdTransport);
+
+  void
+  processConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
+
+  void
+  checkConfig(const ConfigSection& section, const std::string& filename);
+
+  void
+  applyConfig(const ConfigSection& section, const std::string& filename);
+
+  void
+  initialize();
 
 private:
   static Service* s_instance;
 
-  std::string m_configFile;
-  ConfigSection m_configSection;
-
   ndn::KeyChain& m_keyChain;
-  Rib m_rib;
+  ndn::Face m_face;
+  ndn::nfd::Controller m_nfdController;
 
-  unique_ptr<ndn::Face> m_face;
-  unique_ptr<ndn::nfd::Controller> m_nfdController;
-  unique_ptr<FibUpdater> m_fibUpdater;
+  Rib m_rib;
+  FibUpdater m_fibUpdater;
   unique_ptr<AutoPrefixPropagator> m_prefixPropagator;
   unique_ptr<Readvertise> m_readvertiseNlsr;
-  unique_ptr<ndn::mgmt::Dispatcher> m_dispatcher;
-  unique_ptr<RibManager> m_ribManager;
+  ndn::mgmt::Dispatcher m_dispatcher;
+  RibManager m_ribManager;
 };
 
 } // namespace rib
diff --git a/tests/rib/rib-manager.t.cpp b/tests/rib/rib-manager.t.cpp
index 77b1ed3..44b7b29 100644
--- a/tests/rib/rib-manager.t.cpp
+++ b/tests/rib/rib-manager.t.cpp
@@ -45,6 +45,14 @@
   bool isLocalhopConfigured;
 };
 
+static ConfigSection
+getValidatorConfigSection()
+{
+  ConfigSection section;
+  section.put("trust-anchor.type", "any");
+  return section;
+}
+
 class RibManagerFixture : public ManagerCommonFixture
 {
 public:
@@ -55,40 +63,19 @@
     , m_status(status)
     , m_nfdController(m_face, m_keyChain)
     , m_fibUpdater(m_rib, m_nfdController)
-    , m_prefixPropagator(m_nfdController, m_keyChain, m_rib)
-    , m_manager(m_rib, m_dispatcher, m_face, m_nfdController, m_prefixPropagator)
+    , m_manager(m_rib, m_face, m_nfdController, m_dispatcher)
   {
     m_rib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue, this, _1);
 
-    const std::string prefix = "rib\n{\n";
-    const std::string suffix = "}";
-    const std::string localhostSection = "  localhost_security\n"
-    "  {\n"
-    "    trust-anchor\n"
-    "    {\n"
-    "      type any\n"
-    "    }\n"
-    "  }\n";
-    const std::string localhopSection = "  localhop_security\n"
-    "  {\n"
-    "    trust-anchor\n"
-    "    {\n"
-    "      type any\n"
-    "    }\n"
-    "  }\n";
-
-    std::string ribSection = "";
     if (m_status.isLocalhostConfigured) {
-      ribSection += localhostSection;
+      m_manager.applyLocalhostConfig(getValidatorConfigSection(), "test");
     }
     if (m_status.isLocalhopConfigured) {
-      ribSection += localhopSection;
+      m_manager.enableLocalhop(getValidatorConfigSection(), "test");
     }
-    const std::string CONFIG_STR = prefix + ribSection + suffix;
-
-    ConfigFile config;
-    m_manager.setConfigFile(config);
-    config.parse(CONFIG_STR, true, "test-rib");
+    else {
+      m_manager.disableLocalhop();
+    }
 
     registerWithNfd();
 
@@ -231,7 +218,6 @@
   ndn::nfd::Controller m_nfdController;
   Rib m_rib;
   FibUpdater m_fibUpdater;
-  AutoPrefixPropagator m_prefixPropagator;
   RibManager m_manager;
 };
 
diff --git a/tests/rib/rib-service.t.cpp b/tests/rib/service.t.cpp
similarity index 85%
rename from tests/rib/rib-service.t.cpp
rename to tests/rib/service.t.cpp
index 5bfe5b9..14ee649 100644
--- a/tests/rib/rib-service.t.cpp
+++ b/tests/rib/service.t.cpp
@@ -35,21 +35,23 @@
 
 BOOST_AUTO_TEST_CASE(Basic)
 {
+  ConfigSection section;
+  section.put("face_system.unix.path", "/var/run/nfd.sock");
+
   ndn::KeyChain ribKeyChain;
-  const std::string configFile;
 
   BOOST_CHECK_THROW(Service::get(), std::logic_error);
-  BOOST_CHECK_THROW(Service(configFile, ribKeyChain), std::logic_error);
+  BOOST_CHECK_THROW(Service(section, ribKeyChain), std::logic_error);
 
   runOnRibIoService([&] {
     {
       BOOST_CHECK_THROW(Service::get(), std::logic_error);
-      Service ribService(configFile, ribKeyChain);
+      Service ribService(section, ribKeyChain);
       BOOST_CHECK_EQUAL(&ribService, &Service::get());
     }
     BOOST_CHECK_THROW(Service::get(), std::logic_error);
-    Service ribService(configFile, ribKeyChain);
-    BOOST_CHECK_THROW(Service(configFile, ribKeyChain), std::logic_error);
+    Service ribService(section, ribKeyChain);
+    BOOST_CHECK_THROW(Service(section, ribKeyChain), std::logic_error);
   });
 }