security: don't throw when loading an empty validation policy

Refs: #5049
Change-Id: I44feff5f4c83995e7d9f848c3c0cd71825920606
diff --git a/ndn-cxx/security/v2/validation-policy-config.cpp b/ndn-cxx/security/v2/validation-policy-config.cpp
index 29d6f8c..d723b94 100644
--- a/ndn-cxx/security/v2/validation-policy-config.cpp
+++ b/ndn-cxx/security/v2/validation-policy-config.cpp
@@ -35,12 +35,6 @@
 namespace v2 {
 namespace validator_config {
 
-ValidationPolicyConfig::ValidationPolicyConfig()
-  : m_shouldBypass(false)
-  , m_isConfigured(false)
-{
-}
-
 void
 ValidationPolicyConfig::load(const std::string& filename)
 {
@@ -75,6 +69,8 @@
 void
 ValidationPolicyConfig::load(const ConfigSection& configSection, const std::string& filename)
 {
+  BOOST_ASSERT(!filename.empty());
+
   if (m_validator == nullptr) {
     NDN_THROW(Error("Validator instance not assigned on the policy"));
   }
@@ -87,12 +83,6 @@
   }
   m_isConfigured = true;
 
-  BOOST_ASSERT(!filename.empty());
-
-  if (configSection.begin() == configSection.end()) {
-    NDN_THROW(Error("Error processing configuration file " + filename + ": no data"));
-  }
-
   for (const auto& subSection : configSection) {
     const std::string& sectionName = subSection.first;
     const ConfigSection& section = subSection.second;
diff --git a/ndn-cxx/security/v2/validation-policy-config.hpp b/ndn-cxx/security/v2/validation-policy-config.hpp
index 978fdaa..e94ccec 100644
--- a/ndn-cxx/security/v2/validation-policy-config.hpp
+++ b/ndn-cxx/security/v2/validation-policy-config.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,7 +24,6 @@
 
 #include "ndn-cxx/security/v2/validation-policy.hpp"
 #include "ndn-cxx/security/v2/validator-config/rule.hpp"
-#include "ndn-cxx/security/v2/validator-config/common.hpp"
 
 namespace ndn {
 namespace security {
@@ -32,7 +31,7 @@
 namespace validator_config {
 
 /**
- * @brief The validator which can be set up via a configuration file.
+ * @brief A validator that can be set up via a configuration file.
  *
  * @note For command Interest validation, this policy must be combined with
  *       @p ValidationPolicyCommandInterest, in order to guard against replay attacks.
@@ -42,8 +41,6 @@
 class ValidationPolicyConfig : public ValidationPolicy
 {
 public:
-  ValidationPolicyConfig();
-
   /**
    * @brief Load policy from file @p filename
    * @throw Error Validator instance not assigned to the policy (m_validator == nullptr)
@@ -92,13 +89,13 @@
   getDefaultRefreshPeriod();
 
 NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  /** @brief whether to always bypass validation
+  /** @brief Whether to always bypass validation.
    *
    *  This is set to true when 'any' is specified as a trust anchor.
    *  It causes all packets to bypass validation.
    */
-  bool m_shouldBypass;
-  bool m_isConfigured;
+  bool m_shouldBypass = false;
+  bool m_isConfigured = false;
 
   std::vector<unique_ptr<Rule>> m_dataRules;
   std::vector<unique_ptr<Rule>> m_interestRules;
diff --git a/tests/unit/security/v2/validation-policy-config.t.cpp b/tests/unit/security/v2/validation-policy-config.t.cpp
index 9d33a1f..f7a4506 100644
--- a/tests/unit/security/v2/validation-policy-config.t.cpp
+++ b/tests/unit/security/v2/validation-policy-config.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -39,11 +39,28 @@
 using namespace ndn::tests;
 using namespace ndn::security::v2::tests;
 
-
 BOOST_AUTO_TEST_SUITE(Security)
 BOOST_AUTO_TEST_SUITE(V2)
 BOOST_AUTO_TEST_SUITE(TestValidationPolicyConfig)
 
+BOOST_FIXTURE_TEST_CASE(EmptyConfig, HierarchicalValidatorFixture<ValidationPolicyConfig>)
+{
+  this->policy.load(ConfigSection{}, "<empty>");
+
+  BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+  BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+  BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
+  BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
+
+  Data d("/Security/V2/ValidationPolicyConfig/D");
+  this->m_keyChain.sign(d, signingByIdentity(this->identity));
+  VALIDATE_FAILURE(d, "Empty policy should reject everything");
+
+  Interest i("/Security/V2/ValidationPolicyConfig/I");
+  this->m_keyChain.sign(i, signingByIdentity(this->identity));
+  VALIDATE_FAILURE(i, "Empty policy should reject everything");
+}
+
 template<typename Packet>
 class PacketName;
 
@@ -99,10 +116,11 @@
 
   ~ValidationPolicyConfigFixture()
   {
-    boost::filesystem::remove_all(path);
+    boost::system::error_code ec;
+    boost::filesystem::remove_all(path, ec);
   }
 
-public:
+protected:
   using Packet = PacketType;
 
   const boost::filesystem::path path;
@@ -139,15 +157,16 @@
   {
     std::string configFile = (this->path / "config.conf").string();
     {
-      std::ofstream config(configFile.c_str());
+      std::ofstream config(configFile);
       config << this->baseConfig << R"CONF(
-        trust-anchor
-        {
-          type file
-          file-name "trust-anchor.ndncert"
-        }
-      )CONF";
+          trust-anchor
+          {
+            type file
+            file-name "trust-anchor.ndncert"
+          }
+        )CONF";
     }
+
     this->saveCertificate(this->identity, (this->path / "identity.ndncert").string());
 
     BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
@@ -193,9 +212,11 @@
     BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
 
     std::ostringstream os;
-    using namespace ndn::security::transform;
-    const auto& cert = this->identity.getDefaultKey().getDefaultCertificate();
-    bufferSource(cert.wireEncode().wire(), cert.wireEncode().size()) >> base64Encode(false) >> streamSink(os);
+    {
+      using namespace ndn::security::transform;
+      const auto& cert = this->identity.getDefaultKey().getDefaultCertificate().wireEncode();
+      bufferSource(cert.wire(), cert.size()) >> base64Encode(false) >> streamSink(os);
+    }
 
     this->policy.load(this->baseConfig + R"CONF(
         trust-anchor
@@ -481,11 +502,9 @@
 
 using RefreshPolicies = boost::mpl::vector<Refresh1h, Refresh1m, Refresh1s>;
 
-// Somehow, didn't work without this wrapper
 template<typename RefreshPolicy>
 class RefreshPolicyFixture : public LoadStringWithDirAnchor<Data, RefreshPolicy>
 {
-public:
 };
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateRefresh, Refresh, RefreshPolicies, RefreshPolicyFixture<Refresh>)