src: Reorganizing source code in preparation to merge NRD code
Note that as of this commit, there are several changes in location of
compiled binaries in `build/` folder:
* `nfd` has been moved to `build/bin/nfd`
* `unit-tests` has been split into `unit-tests-core` and `unit-tests-daemon`
Change-Id: I2c830c117879edbaa5457d6423c13f0273285919
Refs: #1486
diff --git a/tests/daemon/table/pit.cpp b/tests/daemon/table/pit.cpp
new file mode 100644
index 0000000..c77c909
--- /dev/null
+++ b/tests/daemon/table/pit.cpp
@@ -0,0 +1,383 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014 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
+ *
+ * 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 "table/pit.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TablePit, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(EntryInOutRecords)
+{
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
+ Name name("ndn:/KuYfjtRq");
+ shared_ptr<Interest> interest = makeInterest(name);
+ shared_ptr<Interest> interest1 = makeInterest(name);
+ interest1->setInterestLifetime(time::milliseconds(2528));
+ interest1->setNonce(25559);
+ shared_ptr<Interest> interest2 = makeInterest(name);
+ interest2->setInterestLifetime(time::milliseconds(6464));
+ interest2->setNonce(19004);
+ shared_ptr<Interest> interest3 = makeInterest(name);
+ interest3->setInterestLifetime(time::milliseconds(3585));
+ interest3->setNonce(24216);
+ shared_ptr<Interest> interest4 = makeInterest(name);
+ interest4->setInterestLifetime(time::milliseconds(8795));
+ interest4->setNonce(17365);
+
+ pit::Entry entry(*interest);
+
+ BOOST_CHECK_EQUAL(entry.getInterest().getName(), name);
+ BOOST_CHECK_EQUAL(entry.getName(), name);
+
+ const pit::InRecordCollection& inRecords1 = entry.getInRecords();
+ BOOST_CHECK_EQUAL(inRecords1.size(), 0);
+ const pit::OutRecordCollection& outRecords1 = entry.getOutRecords();
+ BOOST_CHECK_EQUAL(outRecords1.size(), 0);
+
+ // insert InRecord
+ time::steady_clock::TimePoint before1 = time::steady_clock::now();
+ pit::InRecordCollection::iterator in1 =
+ entry.insertOrUpdateInRecord(face1, *interest1);
+ time::steady_clock::TimePoint after1 = time::steady_clock::now();
+ const pit::InRecordCollection& inRecords2 = entry.getInRecords();
+ BOOST_CHECK_EQUAL(inRecords2.size(), 1);
+ BOOST_CHECK(in1 == inRecords2.begin());
+ BOOST_CHECK_EQUAL(in1->getFace(), face1);
+ BOOST_CHECK_EQUAL(in1->getLastNonce(), interest1->getNonce());
+ BOOST_CHECK_GE(in1->getLastRenewed(), before1);
+ BOOST_CHECK_LE(in1->getLastRenewed(), after1);
+ BOOST_CHECK_LE(in1->getExpiry() - in1->getLastRenewed()
+ - interest1->getInterestLifetime(),
+ (after1 - before1));
+
+ // insert OutRecord
+ time::steady_clock::TimePoint before2 = time::steady_clock::now();
+ pit::OutRecordCollection::iterator out1 =
+ entry.insertOrUpdateOutRecord(face1, *interest1);
+ time::steady_clock::TimePoint after2 = time::steady_clock::now();
+ const pit::OutRecordCollection& outRecords2 = entry.getOutRecords();
+ BOOST_CHECK_EQUAL(outRecords2.size(), 1);
+ BOOST_CHECK(out1 == outRecords2.begin());
+ BOOST_CHECK_EQUAL(out1->getFace(), face1);
+ BOOST_CHECK_EQUAL(out1->getLastNonce(), interest1->getNonce());
+ BOOST_CHECK_GE(out1->getLastRenewed(), before2);
+ BOOST_CHECK_LE(out1->getLastRenewed(), after2);
+ BOOST_CHECK_LE(out1->getExpiry() - out1->getLastRenewed()
+ - interest1->getInterestLifetime(),
+ (after2 - before2));
+
+ // update InRecord
+ time::steady_clock::TimePoint before3 = time::steady_clock::now();
+ pit::InRecordCollection::iterator in2 =
+ entry.insertOrUpdateInRecord(face1, *interest2);
+ time::steady_clock::TimePoint after3 = time::steady_clock::now();
+ const pit::InRecordCollection& inRecords3 = entry.getInRecords();
+ BOOST_CHECK_EQUAL(inRecords3.size(), 1);
+ BOOST_CHECK(in2 == inRecords3.begin());
+ BOOST_CHECK_EQUAL(in2->getFace(), face1);
+ BOOST_CHECK_EQUAL(in2->getLastNonce(), interest2->getNonce());
+ BOOST_CHECK_LE(in2->getExpiry() - in2->getLastRenewed()
+ - interest2->getInterestLifetime(),
+ (after3 - before3));
+
+ // insert another InRecord
+ pit::InRecordCollection::iterator in3 =
+ entry.insertOrUpdateInRecord(face2, *interest3);
+ const pit::InRecordCollection& inRecords4 = entry.getInRecords();
+ BOOST_CHECK_EQUAL(inRecords4.size(), 2);
+ BOOST_CHECK_EQUAL(in3->getFace(), face2);
+
+ // delete all InRecords
+ entry.deleteInRecords();
+ const pit::InRecordCollection& inRecords5 = entry.getInRecords();
+ BOOST_CHECK_EQUAL(inRecords5.size(), 0);
+
+ // insert another OutRecord
+ pit::OutRecordCollection::iterator out2 =
+ entry.insertOrUpdateOutRecord(face2, *interest4);
+ const pit::OutRecordCollection& outRecords3 = entry.getOutRecords();
+ BOOST_CHECK_EQUAL(outRecords3.size(), 2);
+ BOOST_CHECK_EQUAL(out2->getFace(), face2);
+
+ // delete OutRecord
+ entry.deleteOutRecord(face2);
+ const pit::OutRecordCollection& outRecords4 = entry.getOutRecords();
+ BOOST_REQUIRE_EQUAL(outRecords4.size(), 1);
+ BOOST_CHECK_EQUAL(outRecords4.begin()->getFace(), face1);
+}
+
+BOOST_AUTO_TEST_CASE(EntryNonce)
+{
+ shared_ptr<Interest> interest = makeInterest("ndn:/qtCQ7I1c");
+
+ pit::Entry entry(*interest);
+
+ BOOST_CHECK_EQUAL(entry.addNonce(25559), true);
+ BOOST_CHECK_EQUAL(entry.addNonce(25559), false);
+ BOOST_CHECK_EQUAL(entry.addNonce(19004), true);
+ BOOST_CHECK_EQUAL(entry.addNonce(19004), false);
+}
+
+BOOST_AUTO_TEST_CASE(EntryLifetime)
+{
+ shared_ptr<Interest> interest = makeInterest("ndn:/7oIEurbgy6");
+ BOOST_ASSERT(interest->getInterestLifetime() < time::milliseconds::zero()); // library uses -1 to indicate unset lifetime
+
+ shared_ptr<Face> face = make_shared<DummyFace>();
+ pit::Entry entry(*interest);
+
+ pit::InRecordCollection::iterator inIt = entry.insertOrUpdateInRecord(face, *interest);
+ BOOST_CHECK_GT(inIt->getExpiry(), time::steady_clock::now());
+
+ pit::OutRecordCollection::iterator outIt = entry.insertOrUpdateOutRecord(face, *interest);
+ BOOST_CHECK_GT(outIt->getExpiry(), time::steady_clock::now());
+}
+
+BOOST_AUTO_TEST_CASE(EntryCanForwardTo)
+{
+ shared_ptr<Interest> interest = makeInterest("ndn:/WDsuBLIMG");
+ pit::Entry entry(*interest);
+
+ shared_ptr<Face> face1 = make_shared<DummyFace>();
+ shared_ptr<Face> face2 = make_shared<DummyFace>();
+
+ entry.insertOrUpdateInRecord(face1, *interest);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), false);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+
+ entry.insertOrUpdateInRecord(face2, *interest);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), true);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+
+ entry.insertOrUpdateOutRecord(face1, *interest);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face1), false);
+ BOOST_CHECK_EQUAL(entry.canForwardTo(*face2), true);
+}
+
+BOOST_AUTO_TEST_CASE(Insert)
+{
+ Name name1("ndn:/5vzBNnMst");
+ Name name2("ndn:/igSGfEIM62");
+ Exclude exclude1;
+ exclude1.excludeOne(Name::Component("u26p47oep"));
+ Exclude exclude2;
+ exclude2.excludeBefore(Name::Component("u26p47oep"));
+ ndn::KeyLocator keyLocator1("ndn:/sGAE3peMHA");
+ ndn::KeyLocator keyLocator2("ndn:/nIJH6pr4");
+
+ NameTree nameTree(16);
+ Pit pit(nameTree);
+ BOOST_CHECK_EQUAL(pit.size(), 0);
+ std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+
+ // base
+ shared_ptr<Interest> interestA = make_shared<Interest>(name1);
+ insertResult = pit.insert(*interestA);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 1);
+
+ // A+MinSuffixComponents
+ shared_ptr<Interest> interestB = make_shared<Interest>(*interestA);
+ interestB->setMinSuffixComponents(2);
+ insertResult = pit.insert(*interestB);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 2);
+
+ // A+MaxSuffixComponents
+ shared_ptr<Interest> interestC = make_shared<Interest>(*interestA);
+ interestC->setMaxSuffixComponents(4);
+ insertResult = pit.insert(*interestC);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 3);
+
+ // A+KeyLocator1
+ shared_ptr<Interest> interestD = make_shared<Interest>(*interestA);
+ interestD->setPublisherPublicKeyLocator(keyLocator1);
+ insertResult = pit.insert(*interestD);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 4);
+
+ // A+KeyLocator2
+ shared_ptr<Interest> interestE = make_shared<Interest>(*interestA);
+ interestE->setPublisherPublicKeyLocator(keyLocator2);
+ insertResult = pit.insert(*interestE);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 5);
+
+ // A+Exclude1
+ shared_ptr<Interest> interestF = make_shared<Interest>(*interestA);
+ interestF->setExclude(exclude1);
+ insertResult = pit.insert(*interestF);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 6);
+
+ // A+Exclude2
+ shared_ptr<Interest> interestG = make_shared<Interest>(*interestA);
+ interestG->setExclude(exclude2);
+ insertResult = pit.insert(*interestG);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 7);
+
+ // A+ChildSelector0
+ shared_ptr<Interest> interestH = make_shared<Interest>(*interestA);
+ interestH->setChildSelector(0);
+ insertResult = pit.insert(*interestH);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 8);
+
+ // A+ChildSelector1
+ shared_ptr<Interest> interestI = make_shared<Interest>(*interestA);
+ interestI->setChildSelector(1);
+ insertResult = pit.insert(*interestI);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 9);
+
+ // A+MustBeFresh
+ shared_ptr<Interest> interestJ = make_shared<Interest>(*interestA);
+ interestJ->setMustBeFresh(true);
+ insertResult = pit.insert(*interestJ);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 10);
+
+ // A+InterestLifetime
+ shared_ptr<Interest> interestK = make_shared<Interest>(*interestA);
+ interestK->setInterestLifetime(time::milliseconds(1000));
+ insertResult = pit.insert(*interestK);
+ BOOST_CHECK_EQUAL(insertResult.second, false);// only guiders differ
+ BOOST_CHECK_EQUAL(pit.size(), 10);
+
+ // A+Nonce
+ shared_ptr<Interest> interestL = make_shared<Interest>(*interestA);
+ interestL->setNonce(2192);
+ insertResult = pit.insert(*interestL);
+ BOOST_CHECK_EQUAL(insertResult.second, false);// only guiders differ
+ BOOST_CHECK_EQUAL(pit.size(), 10);
+
+ // different Name+Exclude1
+ shared_ptr<Interest> interestM = make_shared<Interest>(name2);
+ interestM->setExclude(exclude1);
+ insertResult = pit.insert(*interestM);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 11);
+}
+
+BOOST_AUTO_TEST_CASE(Erase)
+{
+ Interest interest(Name("ndn:/z88Admz6A2"));
+
+ NameTree nameTree(16);
+ Pit pit(nameTree);
+
+ std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+
+ BOOST_CHECK_EQUAL(pit.size(), 0);
+
+ insertResult = pit.insert(interest);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 1);
+
+ insertResult = pit.insert(interest);
+ BOOST_CHECK_EQUAL(insertResult.second, false);
+ BOOST_CHECK_EQUAL(pit.size(), 1);
+
+ pit.erase(insertResult.first);
+ BOOST_CHECK_EQUAL(pit.size(), 0);
+
+ insertResult = pit.insert(interest);
+ BOOST_CHECK_EQUAL(insertResult.second, true);
+ BOOST_CHECK_EQUAL(pit.size(), 1);
+
+}
+
+BOOST_AUTO_TEST_CASE(FindAllDataMatches)
+{
+ Name nameA ("ndn:/A");
+ Name nameAB ("ndn:/A/B");
+ Name nameABC ("ndn:/A/B/C");
+ Name nameABCD("ndn:/A/B/C/D");
+ Name nameD ("ndn:/D");
+
+ Interest interestA (nameA );
+ Interest interestABC(nameABC);
+ Interest interestD (nameD );
+
+ NameTree nameTree(16);
+ Pit pit(nameTree);
+ int count = 0;
+
+ BOOST_CHECK_EQUAL(pit.size(), 0);
+
+ pit.insert(interestA );
+ pit.insert(interestABC);
+ pit.insert(interestD );
+
+ nameTree.lookup(nameABCD); // make sure /A/B/C/D is in nameTree
+
+ BOOST_CHECK_EQUAL(pit.size(), 3);
+
+ Data data(nameABCD);
+
+ shared_ptr<pit::DataMatchResult> matches = pit.findAllDataMatches(data);
+
+ bool hasA = false;
+ bool hasAB = false;
+ bool hasABC = false;
+ bool hasD = false;
+
+ for (pit::DataMatchResult::iterator it = matches->begin();
+ it != matches->end(); ++it) {
+ ++count;
+ shared_ptr<pit::Entry> entry = *it;
+
+ if (entry->getName().equals(nameA ))
+ hasA = true;
+
+ if (entry->getName().equals(nameAB))
+ hasAB = true;
+
+ if (entry->getName().equals(nameABC))
+ hasABC = true;
+
+ if (entry->getName().equals(nameD))
+ hasD = true;
+ }
+ BOOST_CHECK_EQUAL(hasA , true);
+ BOOST_CHECK_EQUAL(hasAB , false);
+ BOOST_CHECK_EQUAL(hasABC, true);
+ BOOST_CHECK_EQUAL(hasD , false);
+
+ BOOST_CHECK_EQUAL(count, 2);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nfd