build: Reviving support for precompiled headers
This commit also includes an update of ./waf, which has several
improvements. In particular, clang++ is now default compiler on OSX
platform.
This commit also includes reorganization of tests. All unit tests are
now under tests/unit-tests and integrated tests are under
tests/integrated. This change allows small compilation optimization,
partially related to precompiled headers.
Change-Id: I4c171c04d18e9cb83e461264a35b9ed85ea4d50e
diff --git a/tests/integrated/test-faces.cpp b/tests/integrated/test-faces.cpp
new file mode 100644
index 0000000..c86cd62
--- /dev/null
+++ b/tests/integrated/test-faces.cpp
@@ -0,0 +1,481 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "face.hpp"
+#include "util/scheduler.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+
+
+class FacesFixture
+{
+public:
+ FacesFixture()
+ : nData(0)
+ , nTimeouts(0)
+ , regPrefixId(0)
+ , nInInterests(0)
+ , nInInterests2(0)
+ , nRegFailures(0)
+ {
+ }
+
+ void
+ onData()
+ {
+ ++nData;
+ }
+
+ void
+ onTimeout()
+ {
+ ++nTimeouts;
+ }
+
+ void
+ onInterest(Face& face,
+ const Name&, const Interest&)
+ {
+ ++nInInterests;
+
+ face.unsetInterestFilter(regPrefixId);
+ }
+
+ void
+ onInterest2(Face& face,
+ const Name&, const Interest&)
+ {
+ ++nInInterests2;
+
+ face.unsetInterestFilter(regPrefixId2);
+ }
+
+ void
+ onInterestRegex(Face& face,
+ const InterestFilter&, const Interest&)
+ {
+ ++nInInterests;
+ }
+
+ void
+ onInterestRegexError(Face& face,
+ const Name&, const Interest&)
+ {
+ BOOST_FAIL("InterestFilter::Error should have been triggered");
+ }
+
+ void
+ onRegFailed()
+ {
+ ++nRegFailures;
+ }
+
+ void
+ expressInterest(Face& face, const Name& name)
+ {
+ Interest i(name);
+ i.setInterestLifetime(time::milliseconds(50));
+ face.expressInterest(i,
+ bind(&FacesFixture::onData, this),
+ bind(&FacesFixture::onTimeout, this));
+ }
+
+ void
+ terminate(Face& face)
+ {
+ face.shutdown();
+ }
+
+ uint32_t nData;
+ uint32_t nTimeouts;
+
+ const RegisteredPrefixId* regPrefixId;
+ const RegisteredPrefixId* regPrefixId2;
+ uint32_t nInInterests;
+ uint32_t nInInterests2;
+ uint32_t nRegFailures;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestFaces, FacesFixture)
+
+BOOST_AUTO_TEST_CASE(Unix)
+{
+ Face face;
+
+ face.expressInterest(Interest("/", time::milliseconds(1000)),
+ bind(&FacesFixture::onData, this),
+ bind(&FacesFixture::onTimeout, this));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nData, 1);
+ BOOST_CHECK_EQUAL(nTimeouts, 0);
+
+ face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
+ time::milliseconds(50)),
+ bind(&FacesFixture::onData, this),
+ bind(&FacesFixture::onTimeout, this));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nData, 1);
+ BOOST_CHECK_EQUAL(nTimeouts, 1);
+}
+
+BOOST_AUTO_TEST_CASE(Tcp)
+{
+ Face face("localhost");
+
+ face.expressInterest(Interest("/", time::milliseconds(1000)),
+ bind(&FacesFixture::onData, this),
+ bind(&FacesFixture::onTimeout, this));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nData, 1);
+ BOOST_CHECK_EQUAL(nTimeouts, 0);
+
+ face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
+ time::milliseconds(50)),
+ bind(&FacesFixture::onData, this),
+ bind(&FacesFixture::onTimeout, this));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nData, 1);
+ BOOST_CHECK_EQUAL(nTimeouts, 1);
+}
+
+
+BOOST_AUTO_TEST_CASE(SetFilter)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::milliseconds(300),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ regPrefixId = face.setInterestFilter("/Hello/World",
+ bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/!")));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nInInterests, 1);
+ BOOST_CHECK_EQUAL(nTimeouts, 1);
+ BOOST_CHECK_EQUAL(nData, 0);
+}
+
+BOOST_AUTO_TEST_CASE(SetTwoFilters)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ regPrefixId = face.setInterestFilter("/Hello/World",
+ bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face.setInterestFilter("/Los/Angeles/Lakers",
+ bind(&FacesFixture::onInterest2, this, ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/!")));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nInInterests, 1);
+ BOOST_CHECK_EQUAL(nInInterests2, 0);
+ BOOST_CHECK_EQUAL(nTimeouts, 1);
+ BOOST_CHECK_EQUAL(nData, 0);
+}
+
+BOOST_AUTO_TEST_CASE(SetRegexFilterError)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+ bind(&FacesFixture::onInterestRegexError, this,
+ ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::milliseconds(300),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/XXX/b/c"))); // should match
+
+ BOOST_REQUIRE_THROW(face.processEvents(), InterestFilter::Error);
+}
+
+BOOST_AUTO_TEST_CASE(SetRegexFilter)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(2),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+ bind(&FacesFixture::onInterestRegex, this,
+ ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a"))); // shouldn't match
+
+ scheduler.scheduleEvent(time::milliseconds(300),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b"))); // should match
+
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/c"))); // should match
+
+ scheduler.scheduleEvent(time::milliseconds(500),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/d"))); // should not match
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nInInterests, 2);
+ BOOST_CHECK_EQUAL(nTimeouts, 4);
+ BOOST_CHECK_EQUAL(nData, 0);
+}
+
+class FacesFixture2 : public FacesFixture
+{
+public:
+ void
+ checkPrefix(bool doesExist)
+ {
+ int result = std::system("nfd-status | grep /Hello/World >/dev/null");
+
+ if (doesExist) {
+ BOOST_CHECK_EQUAL(result, 0);
+ }
+ else {
+ BOOST_CHECK_NE(result, 0);
+ }
+ }
+};
+
+BOOST_FIXTURE_TEST_CASE(RegisterUnregisterPrefix, FacesFixture2)
+{
+ Face face;
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(2),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World"),
+ bind(&FacesFixture::onInterest, this,
+ ref(face), _1, _2),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::milliseconds(500),
+ bind(&FacesFixture2::checkPrefix, this, true));
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(static_cast<void(Face::*)(const RegisteredPrefixId*)>(&Face::unsetInterestFilter),
+ &face,
+ regPrefixId)); // shouldn't match
+
+ scheduler.scheduleEvent(time::milliseconds(1500),
+ bind(&FacesFixture2::checkPrefix, this, false));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+}
+
+
+class FacesFixture3 : public FacesFixture2
+{
+public:
+ FacesFixture3()
+ : nRegSuccesses(0)
+ , nUnregSuccesses(0)
+ , nUnregFailures(0)
+ {
+ }
+
+ void
+ onRegSucceeded()
+ {
+ ++nRegSuccesses;
+ }
+
+ void
+ onUnregSucceeded()
+ {
+ ++nUnregSuccesses;
+ }
+
+ void
+ onUnregFailed()
+ {
+ ++nUnregFailures;
+ }
+
+public:
+ uint64_t nRegSuccesses;
+ uint64_t nUnregSuccesses;
+ uint64_t nUnregFailures;
+};
+
+BOOST_FIXTURE_TEST_CASE(RegisterPrefix, FacesFixture3)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(2),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ scheduler.scheduleEvent(time::milliseconds(500),
+ bind(&FacesFixture2::checkPrefix, this, true));
+
+ regPrefixId = face.registerPrefix("/Hello/World",
+ bind(&FacesFixture3::onRegSucceeded, this),
+ bind(&FacesFixture3::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&Face::unregisterPrefix, &face,
+ regPrefixId,
+ static_cast<UnregisterPrefixSuccessCallback>(bind(&FacesFixture3::onUnregSucceeded, this)),
+ static_cast<UnregisterPrefixFailureCallback>(bind(&FacesFixture3::onUnregFailed, this))));
+
+ scheduler.scheduleEvent(time::milliseconds(1500),
+ bind(&FacesFixture2::checkPrefix, this, false));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nRegSuccesses, 1);
+
+ BOOST_CHECK_EQUAL(nUnregFailures, 0);
+ BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
+}
+
+BOOST_AUTO_TEST_CASE(SetRegexFilterButNoRegister)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(2),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+ bind(&FacesFixture::onInterestRegex, this,
+ ref(face), _1, _2));
+
+ // prefix is not registered, and also does not match regex
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a")));
+
+ // matches regex, but prefix is not registered
+ scheduler.scheduleEvent(time::milliseconds(300),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b")));
+
+ // matches regex, but prefix is not registered
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/c")));
+
+ // prefix is not registered, and also does not match regex
+ scheduler.scheduleEvent(time::milliseconds(500),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/d")));
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nInInterests, 0);
+ BOOST_CHECK_EQUAL(nTimeouts, 4);
+ BOOST_CHECK_EQUAL(nData, 0);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(SetRegexFilterAndRegister, FacesFixture3)
+{
+ Face face;
+ Face face2(face.getIoService());
+ Scheduler scheduler(face.getIoService());
+ scheduler.scheduleEvent(time::seconds(2),
+ bind(&FacesFixture::terminate, this, ref(face)));
+
+ face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+ bind(&FacesFixture::onInterestRegex, this,
+ ref(face), _1, _2));
+
+ face.registerPrefix("/Hello/World",
+ bind(&FacesFixture3::onRegSucceeded, this),
+ bind(&FacesFixture3::onRegFailed, this));
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a"))); // shouldn't match
+
+ scheduler.scheduleEvent(time::milliseconds(300),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b"))); // should match
+
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/c"))); // should match
+
+ scheduler.scheduleEvent(time::milliseconds(500),
+ bind(&FacesFixture::expressInterest, this,
+ ref(face2), Name("/Hello/World/a/b/d"))); // should not match
+
+ BOOST_REQUIRE_NO_THROW(face.processEvents());
+
+ BOOST_CHECK_EQUAL(nRegFailures, 0);
+ BOOST_CHECK_EQUAL(nRegSuccesses, 1);
+
+ BOOST_CHECK_EQUAL(nInInterests, 2);
+ BOOST_CHECK_EQUAL(nTimeouts, 4);
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace ndn
diff --git a/tests/integrated/test-validator-config.cpp b/tests/integrated/test-validator-config.cpp
new file mode 100644
index 0000000..1f118af
--- /dev/null
+++ b/tests/integrated/test-validator-config.cpp
@@ -0,0 +1,1018 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <yingdi0@cs.ucla.edu>
+ */
+
+#include "security/validator-config.hpp"
+
+#include "security/key-chain.hpp"
+#include "util/io.hpp"
+#include "util/scheduler.hpp"
+
+#include <boost/asio.hpp>
+
+#include "boost-test.hpp"
+
+using namespace std;
+
+namespace ndn {
+
+BOOST_AUTO_TEST_SUITE(TestValidatorConfig)
+
+void
+onValidated(const shared_ptr<const Data>& data)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidationFailed(const shared_ptr<const Data>& data, const string& failureInfo)
+{
+ std::cerr << "Failure Info: " << failureInfo << std::endl;
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureValidated(const shared_ptr<const Data>& data)
+{
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureInvalidated(const shared_ptr<const Data>& data, const string& failureInfo)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidated2(const shared_ptr<const Interest>& interest)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidationFailed2(const shared_ptr<const Interest>& interest, const string& failureInfo)
+{
+ std::cerr << "Interest Name: " << interest->getName() << std::endl;
+ std::cerr << "Failure Info: " << failureInfo << std::endl;
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureValidated2(const shared_ptr<const Interest>& interest)
+{
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureInvalidated2(const shared_ptr<const Interest>& interest,
+ const string& failureInfo)
+{
+ BOOST_CHECK(true);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-1.cert");
+
+ Name dataName1("/simple/equal");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/different");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/equal\n"
+ " relation equal\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-1.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-1.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter2)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter2");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-2.cert");
+
+ Name dataName1("/simple/isPrefixOf");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/notPrefixOf");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/isPrefixOf/anotherLevel");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple2 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/isPrefixOf\n"
+ " relation is-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-2.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-2.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter3)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter3");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-3.cert");
+
+ Name dataName1("/simple/isStrictPrefixOf");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/isStrictPrefixOf/anotherLevel");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/isStrictPrefixOf\n"
+ " relation is-strict-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-3.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-3.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter4)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter4");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-4.cert");
+
+ Name dataName1("/simple/regex");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/regex-wrong");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/regex/correct");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " regex ^<simple><regex>\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-4.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-4.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(KeyLocatorNameChecker1)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/KeyLocatorNameChecker1");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-5.cert");
+
+ Name dataName1 = identity;
+ dataName1.append("1");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2 = identity;
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/TestValidatorConfig/KeyLocatorNameChecker1");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " hyper-relation\n"
+ " {\n"
+ " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$\n"
+ " k-expand \\\\1\\\\2\n"
+ " h-relation is-strict-prefix-of\n"
+ " p-regex ^(<>*)$\n"
+ " p-expand \\\\1\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-5.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-5.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+struct FacesFixture
+{
+ FacesFixture()
+ : regPrefixId(0)
+ , regPrefixId2(0)
+ {}
+
+ void
+ onInterest(shared_ptr<Face> face, shared_ptr<Data> data)
+ {
+ face->put(*data);
+ face->unsetInterestFilter(regPrefixId);
+ }
+
+ void
+ onInterest2(shared_ptr<Face> face, shared_ptr<Data> data)
+ {
+ face->put(*data);
+ face->unsetInterestFilter(regPrefixId2);
+ }
+
+ void
+ onRegFailed()
+ {}
+
+ void
+ validate1(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
+ {
+ validator->validate(*data,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+ }
+
+ void
+ validate2(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
+ {
+ validator->validate(*data,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+ }
+
+ void
+ validate3(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
+ {
+ validator->validate(*interest,
+ bind(&onValidated2, _1),
+ bind(&onValidationFailed2, _1, _2));
+ }
+
+ void
+ validate4(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
+ {
+ validator->validate(*interest,
+ bind(&onIntentionalFailureValidated2, _1),
+ bind(&onIntentionalFailureInvalidated2, _1, _2));
+ }
+
+ void
+ terminate(shared_ptr<Face> face)
+ {
+ face->getIoService().stop();
+ }
+
+ const RegisteredPrefixId* regPrefixId;
+ const RegisteredPrefixId* regPrefixId2;
+};
+
+BOOST_FIXTURE_TEST_CASE(HierarchicalChecker, FacesFixture)
+{
+ KeyChain keyChain;
+ std::vector<CertificateSubjectDescription> subjectDescription;
+
+ Name root("/TestValidatorConfig");
+ Name rootCertName = keyChain.createIdentity(root);
+ shared_ptr<IdentityCertificate> rootCert =
+ keyChain.getCertificate(rootCertName);
+ io::save(*rootCert, "trust-anchor-6.cert");
+
+
+ Name sld("/TestValidatorConfig/HierarchicalChecker");
+ Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
+ shared_ptr<IdentityCertificate> sldCert =
+ keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
+ root,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*sldCert, root);
+ keyChain.addCertificateAsIdentityDefault(*sldCert);
+
+ Name nld("/TestValidatorConfig/HierarchicalChecker/NextLevel");
+ Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
+ shared_ptr<IdentityCertificate> nldCert =
+ keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
+ sld,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*nldCert, sld);
+ keyChain.addCertificateAsIdentityDefault(*nldCert);
+
+ shared_ptr<Face> face = make_shared<Face>();
+ Face face2(face->getIoService());
+ Scheduler scheduler(face->getIoService());
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, face));
+
+ regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest, this, face, sldCert),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest2, this, face, nldCert),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ Name dataName1 = nld;
+ dataName1.append("data1");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, nld));
+
+ Name dataName2("/ConfValidatorTest");
+ dataName2.append("data1");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, nld));
+
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " checker\n"
+ " {\n"
+ " type hierarchical\n"
+ " sig-type rsa-sha256\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-6.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
+ validator->load(CONFIG, CONFIG_PATH.native());
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::validate1, this,
+ validator, data1));
+
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::validate2, this,
+ validator, data2));
+
+ BOOST_REQUIRE_NO_THROW(face->processEvents());
+
+ keyChain.deleteIdentity(root);
+ keyChain.deleteIdentity(sld);
+ keyChain.deleteIdentity(nld);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-6.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(FixedSingerChecker)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/FixedSingerChecker");
+
+ Name identity1 = identity;
+ identity1.append("1").appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity1));
+ Name certName1 = keyChain.getDefaultCertificateNameForIdentity(identity1);
+ shared_ptr<IdentityCertificate> idCert1 = keyChain.getCertificate(certName1);
+ io::save(*idCert1, "trust-anchor-7.cert");
+
+ Name identity2 = identity;
+ identity2.append("2").appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity2));
+
+ Name dataName1 = identity;
+ dataName1.append("data").appendVersion();
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity1));
+
+ Name dataName2 = identity;
+ dataName2.append("data").appendVersion();
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity2));
+
+ Name interestName("/TestValidatorConfig/FixedSingerChecker/fakeSigInfo/fakeSigValue");
+ shared_ptr<Interest> interest = make_shared<Interest>(interestName);
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"FixedSingerChecker Data Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /TestValidatorConfig/FixedSingerChecker\n"
+ " relation is-strict-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type fixed-signer\n"
+ " sig-type rsa-sha256\n"
+ " signer\n"
+ " {\n"
+ " type file\n"
+ " file-name \"trust-anchor-7.cert\"\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "rule\n"
+ "{\n"
+ " id \"FixedSingerChecker Interest Rule\"\n"
+ " for interest\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /TestValidatorConfig/FixedSingerChecker\n"
+ " relation is-strict-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type fixed-signer\n"
+ " sig-type rsa-sha256\n"
+ " signer\n"
+ " {\n"
+ " type file\n"
+ " file-name \"trust-anchor-7.cert\"\n"
+ " }\n"
+ " }\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*interest,
+ bind(&onIntentionalFailureValidated2, _1),
+ bind(&onIntentionalFailureInvalidated2, _1, _2));
+
+
+ keyChain.deleteIdentity(identity1);
+ keyChain.deleteIdentity(identity2);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-7.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
+{
+ KeyChain keyChain;
+ std::vector<CertificateSubjectDescription> subjectDescription;
+
+ Name root("/TestValidatorConfig");
+ Name rootCertName = keyChain.createIdentity(root);
+ shared_ptr<IdentityCertificate> rootCert =
+ keyChain.getCertificate(rootCertName);
+ io::save(*rootCert, "trust-anchor-8.cert");
+
+
+ Name sld("/TestValidatorConfig/Nrd-1");
+ Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
+ shared_ptr<IdentityCertificate> sldCert =
+ keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
+ root,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*sldCert, root);
+ keyChain.addCertificateAsIdentityDefault(*sldCert);
+
+ Name nld("/TestValidatorConfig/Nrd-1/Nrd-2");
+ Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
+ shared_ptr<IdentityCertificate> nldCert =
+ keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
+ sld,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*nldCert, sld);
+ keyChain.addCertificateAsIdentityDefault(*nldCert);
+
+ shared_ptr<Face> face = make_shared<Face>();
+ Face face2(face->getIoService());
+ Scheduler scheduler(face->getIoService());
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, face));
+
+ regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest, this, face, sldCert),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest2, this, face, nldCert),
+ RegisterPrefixSuccessCallback(),
+ bind(&FacesFixture::onRegFailed, this));
+
+ Name interestName1("/localhost/nrd/register/option/timestamp/nonce");
+ shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest1, nld));
+
+ Name interestName2("/localhost/nrd/non-register");
+ shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest2, nld));
+
+ Name interestName3("/localhost/nrd/register/option/timestamp/nonce");
+ shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest3, root));
+
+ Name interestName4("/localhost/nrd/register/option/timestamp/nonce/fakeSigInfo/fakeSigValue");
+ shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"NRD Prefix Registration Command Rule\"\n"
+ " for interest\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "rule\n"
+ "{\n"
+ " id \"Testbed Hierarchy Rule\"\n"
+ " for data\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type hierarchical\n"
+ " sig-type rsa-sha256\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-8.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
+ validator->load(CONFIG, CONFIG_PATH.native());
+
+ // should succeed
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::validate3, this,
+ validator, interest1));
+ // should fail
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::validate4, this,
+ validator, interest2));
+ // should succeed
+ scheduler.scheduleEvent(time::milliseconds(600),
+ bind(&FacesFixture::validate3, this,
+ validator, interest3));
+ // should fail
+ scheduler.scheduleEvent(time::milliseconds(600),
+ bind(&FacesFixture::validate4, this,
+ validator, interest4));
+
+ BOOST_REQUIRE_NO_THROW(face->processEvents());
+
+ keyChain.deleteIdentity(root);
+ keyChain.deleteIdentity(sld);
+ keyChain.deleteIdentity(nld);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(Reset)
+{
+ KeyChain keyChain;
+
+ Name root("/TestValidatorConfig/Reload");
+ Name rootCertName = keyChain.createIdentity(root);
+ shared_ptr<IdentityCertificate> rootCert =
+ keyChain.getCertificate(rootCertName);
+ io::save(*rootCert, "trust-anchor-8.cert");
+
+ Face face;
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"NRD Prefix Registration Command Rule\"\n"
+ " for interest\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "rule\n"
+ "{\n"
+ " id \"Testbed Hierarchy Rule\"\n"
+ " for data\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type hierarchical\n"
+ " sig-type rsa-sha256\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-8.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face));
+
+ validator->load(CONFIG, CONFIG_PATH.native());
+ BOOST_CHECK_EQUAL(validator->isEmpty(), false);
+
+ validator->reset();
+ BOOST_CHECK(validator->isEmpty());
+
+ keyChain.deleteIdentity(root);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(Wildcard)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/Wildcard");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+
+ Name dataName1("/any/data");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ std::string CONFIG =
+ "trust-anchor\n"
+ "{\n"
+ " type any\n"
+ "}\n";
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ Face face;
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace ndn
diff --git a/tests/integrated/wscript b/tests/integrated/wscript
new file mode 100644
index 0000000..d5d9af7
--- /dev/null
+++ b/tests/integrated/wscript
@@ -0,0 +1,29 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+from waflib import Utils
+
+top = '..'
+
+def build(bld):
+ unittests = bld(
+ target="integrated-test-objects",
+ name="integrated-test-objects",
+ features="cxx",
+ source=bld.path.ant_glob(['**/*.cpp'],
+ excl=['main.cpp', '**/*-osx.cpp', '**/*-sqlite3.cpp']),
+ use='tests-base',
+ includes='.',
+ install_path=None,
+ )
+
+ if bld.env['HAVE_OSX_SECURITY']:
+ unittests.source += bld.path.ant_glob('**/*-osx.cpp')
+
+ # In case we want to make it optional later
+ unittests.source += bld.path.ant_glob('**/*-sqlite3.cpp')
+
+ bld.program(
+ target="../integrated-tests",
+ use="integrated-test-objects",
+ source="main.cpp",
+ install_path=None)