update: Process Name prefix update commands
refs #1834
Change-Id: I18c86d0743b4a10ce3a8681f202b59a86602e43f
diff --git a/tests/update/test-prefix-update-processor.cpp b/tests/update/test-prefix-update-processor.cpp
new file mode 100644
index 0000000..adb13f4
--- /dev/null
+++ b/tests/update/test-prefix-update-processor.cpp
@@ -0,0 +1,241 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015, The University of Memphis,
+ * Regents of the University of California,
+ * Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR 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.
+ *
+ * NLSR 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
+ * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "update/prefix-update-processor.hpp"
+
+#include "../control-commands.hpp"
+#include "../test-common.hpp"
+#include "nlsr.hpp"
+
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/management/nfd-control-parameters.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include <boost/filesystem.hpp>
+
+using namespace ndn;
+
+namespace nlsr {
+namespace update {
+namespace test {
+
+class PrefixUpdateFixture : public nlsr::test::BaseFixture
+{
+public:
+ PrefixUpdateFixture()
+ : face(ndn::util::makeDummyClientFace(g_ioService))
+ , siteIdentity(ndn::Name("/ndn/edu/test-site").appendVersion())
+ , opIdentity(ndn::Name(siteIdentity).append(ndn::Name("%C1.Operator")).appendVersion())
+ , nlsr(g_ioService, g_scheduler, *face)
+ , keyPrefix(("/ndn/broadcast"))
+ , updateProcessor(nlsr.getPrefixUpdateProcessor())
+ , SITE_CERT_PATH(boost::filesystem::current_path() / std::string("site.cert"))
+ {
+ createSiteCert();
+ BOOST_REQUIRE(siteCert != nullptr);
+
+ createOperatorCert();
+ BOOST_REQUIRE(opCert != nullptr);
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"NLSR ControlCommand Rule\"\n"
+ " for interest\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^<localhost><nlsr><prefix-update>[<advertise><withdraw>]<>$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><ksk-.*><ID-CERT>$\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "rule\n"
+ "{\n"
+ " id \"NLSR 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 \"site.cert\"\n"
+ "}\n";
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test.conf"));
+
+ updateProcessor.getValidator().load(CONFIG, CONFIG_PATH.native());
+
+ // Insert certs after the validator is loaded since ValidatorConfig::load() clears
+ // the certificate cache
+ nlsr.addCertificateToCache(opCert);
+
+ // Set the network so the LSA prefix is constructed
+ nlsr.getConfParameter().setNetwork("/ndn");
+
+ // Initialize NLSR so a sync socket is created
+ nlsr.initialize();
+
+ // Listen on localhost prefix
+ updateProcessor.startListening();
+
+ face->processEvents(ndn::time::milliseconds(1));
+ face->sentInterests.clear();
+ }
+
+ void
+ createSiteCert()
+ {
+ // Site cert
+ keyChain.createIdentity(siteIdentity);
+ siteCertName = keyChain.getDefaultCertificateNameForIdentity(siteIdentity);
+ siteCert = keyChain.getCertificate(siteCertName);
+
+ ndn::io::save(*siteCert, SITE_CERT_PATH.string());
+ }
+
+ void
+ createOperatorCert()
+ {
+ // Operator cert
+ ndn::Name keyName = keyChain.generateRsaKeyPairAsDefault(opIdentity, true);
+
+ opCert = ndn::make_shared<ndn::IdentityCertificate>();
+ ndn::shared_ptr<ndn::PublicKey> pubKey = keyChain.getPublicKey(keyName);
+ opCertName = keyName.getPrefix(-1);
+ opCertName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+ opCert->setName(opCertName);
+ opCert->setNotBefore(time::system_clock::now() - time::days(1));
+ opCert->setNotAfter(time::system_clock::now() + time::days(1));
+ opCert->setPublicKeyInfo(*pubKey);
+ opCert->addSubjectDescription(CertificateSubjectDescription(ndn::oid::ATTRIBUTE_NAME,
+ keyName.toUri()));
+ opCert->encode();
+
+ keyChain.signByIdentity(*opCert, siteIdentity);
+
+ keyChain.addCertificateAsIdentityDefault(*opCert);
+ }
+
+ bool
+ wasRoutingUpdatePublished()
+ {
+ const ndn::Name& lsaPrefix = nlsr.getConfParameter().getLsaPrefix();
+
+ const auto& it = std::find_if(face->sentDatas.begin(), face->sentDatas.end(),
+ [lsaPrefix] (const ndn::Data& data) {
+ return lsaPrefix.isPrefixOf(data.getName());
+ });
+
+ return (it != face->sentDatas.end());
+ }
+
+ ~PrefixUpdateFixture()
+ {
+ keyChain.deleteIdentity(siteIdentity);
+ keyChain.deleteIdentity(opIdentity);
+
+ boost::filesystem::remove(SITE_CERT_PATH);
+ }
+
+public:
+ shared_ptr<ndn::util::DummyClientFace> face;
+ ndn::KeyChain keyChain;
+
+ ndn::Name siteIdentity;
+ ndn::Name siteCertName;
+ shared_ptr<IdentityCertificate> siteCert;
+
+ ndn::Name opIdentity;
+ ndn::Name opCertName;
+ shared_ptr<IdentityCertificate> opCert;
+
+ Nlsr nlsr;
+ ndn::Name keyPrefix;
+ PrefixUpdateProcessor& updateProcessor;
+
+ const boost::filesystem::path SITE_CERT_PATH;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestPrefixUpdateProcessor, PrefixUpdateFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+ // Advertise
+ ndn::nfd::ControlParameters parameters;
+ parameters.setName("/prefix/to/advertise/");
+
+ ndn::Name advertiseCommand("/localhost/nlsr/prefix-update/advertise");
+ advertiseCommand.append(parameters.wireEncode());
+
+ shared_ptr<Interest> advertiseInterest = make_shared<Interest>(advertiseCommand);
+ keyChain.signByIdentity(*advertiseInterest, opIdentity);
+
+ face->receive(*advertiseInterest);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ NamePrefixList& namePrefixList = nlsr.getNamePrefixList();
+
+ BOOST_REQUIRE_EQUAL(namePrefixList.getSize(), 1);
+ BOOST_CHECK_EQUAL(namePrefixList.getNameList().front(), parameters.getName());
+
+ BOOST_CHECK(wasRoutingUpdatePublished());
+ face->sentDatas.clear();
+
+ // Withdraw
+ ndn::Name withdrawCommand("/localhost/nlsr/prefix-update/withdraw");
+ withdrawCommand.append(parameters.wireEncode());
+
+ shared_ptr<Interest> withdrawInterest = make_shared<Interest>(withdrawCommand);
+ keyChain.signByIdentity(*withdrawInterest, opIdentity);
+
+ face->receive(*withdrawInterest);
+ face->processEvents(ndn::time::milliseconds(1));
+
+ BOOST_CHECK_EQUAL(namePrefixList.getSize(), 0);
+
+ BOOST_CHECK(wasRoutingUpdatePublished());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace update
+} // namespace nlsr