blob: 4411fd20bb11ca63565b5519fa38e8bc43a413a4 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (C) 2014 Named Data Networking Project
* See COPYING for copyright and distribution information.
*/
#include "table/name-tree.hpp"
#include "tests/test-common.hpp"
namespace nfd {
namespace tests {
using name_tree::Entry;
BOOST_FIXTURE_TEST_SUITE(TableNameTree, BaseFixture)
BOOST_AUTO_TEST_CASE(Entry)
{
Name prefix("ndn:/named-data/research/abc/def/ghi");
name_tree::Entry npe = name_tree::Entry(prefix);
BOOST_CHECK_EQUAL(npe.getPrefix(), prefix);
// examine all the get methods
uint32_t hash = npe.getHash();
BOOST_CHECK_EQUAL(hash, 0);
shared_ptr<name_tree::Entry> parent = npe.getParent();
BOOST_CHECK(!static_cast<bool>(parent));
std::vector<shared_ptr<name_tree::Entry> >& childList = npe.getChildren();
BOOST_CHECK_EQUAL(childList.size(), 0);
shared_ptr<fib::Entry> fib = npe.getFibEntry();
BOOST_CHECK(!static_cast<bool>(fib));
std::vector< shared_ptr<pit::Entry> >& pitList = npe.getPitEntries();
BOOST_CHECK_EQUAL(pitList.size(), 0);
// examine all the set method
npe.setHash(12345);
BOOST_CHECK_EQUAL(npe.getHash(), 12345);
Name parentName("ndn:/named-data/research/abc/def");
parent = make_shared<name_tree::Entry>(parentName);
npe.setParent(parent);
BOOST_CHECK_EQUAL(npe.getParent(), parent);
// Insert FIB
shared_ptr<fib::Entry> fibEntry(new fib::Entry(prefix));
shared_ptr<fib::Entry> fibEntryParent(new fib::Entry(parentName));
npe.setFibEntry(fibEntry);
BOOST_CHECK_EQUAL(npe.getFibEntry(), fibEntry);
// Erase a FIB that does not exist
BOOST_CHECK_EQUAL(npe.
eraseFibEntry(fibEntryParent), false);
BOOST_CHECK_EQUAL(npe.getFibEntry(), fibEntry);
// Erase the FIB that exists
BOOST_CHECK_EQUAL(npe.
eraseFibEntry(fibEntry), true);
BOOST_CHECK(!static_cast<bool>(npe.getFibEntry()));
// Insert a PIT
shared_ptr<pit::Entry> PitEntry(make_shared<pit::Entry>(prefix));
shared_ptr<pit::Entry> PitEntry2(make_shared<pit::Entry>(parentName));
Name prefix3("ndn:/named-data/research/abc/def");
shared_ptr<pit::Entry> PitEntry3(make_shared<pit::Entry>(prefix3));
npe.insertPitEntry(PitEntry);
BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 1);
npe.insertPitEntry(PitEntry2);
BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 2);
BOOST_CHECK_EQUAL(npe.
erasePitEntry(PitEntry), true);
BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 1);
// erase a PIT Entry that does not exist
BOOST_CHECK_EQUAL(npe.
erasePitEntry(PitEntry3), false);
BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 1);
BOOST_CHECK_EQUAL(npe.
erasePitEntry(PitEntry2), true);
BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 0);
// erase a PIT Entry that does not exist any more
BOOST_CHECK_EQUAL(npe.
erasePitEntry(PitEntry2), false);
}
BOOST_AUTO_TEST_CASE(NameTreeBasic)
{
size_t nBuckets = 16;
NameTree nt(nBuckets);
BOOST_CHECK_EQUAL(nt.size(), 0);
BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
Name nameABC = ("ndn:/a/b/c");
shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
BOOST_CHECK_EQUAL(nt.size(), 4);
Name nameABD = ("/a/b/d");
shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
BOOST_CHECK_EQUAL(nt.size(), 5);
Name nameAE = ("/a/e/");
shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
BOOST_CHECK_EQUAL(nt.size(), 6);
Name nameF = ("/f");
shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
BOOST_CHECK_EQUAL(nt.size(), 7);
// validate lookup() and findExactMatch()
Name nameAB ("/a/b");
BOOST_CHECK_EQUAL(npeABC->getParent(), nt.findExactMatch(nameAB));
BOOST_CHECK_EQUAL(npeABD->getParent(), nt.findExactMatch(nameAB));
Name nameA ("/a");
BOOST_CHECK_EQUAL(npeAE->getParent(), nt.findExactMatch(nameA));
Name nameRoot ("/");
BOOST_CHECK_EQUAL(npeF->getParent(), nt.findExactMatch(nameRoot));
BOOST_CHECK_EQUAL(nt.size(), 7);
Name name0 = ("/does/not/exist");
shared_ptr<name_tree::Entry> npe0 = nt.findExactMatch(name0);
BOOST_CHECK(!static_cast<bool>(npe0));
// Longest Prefix Matching
shared_ptr<name_tree::Entry> temp;
Name nameABCLPM("/a/b/c/def/asdf/nlf");
temp = nt.findLongestPrefixMatch(nameABCLPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABC));
Name nameABDLPM("/a/b/d/def/asdf/nlf");
temp = nt.findLongestPrefixMatch(nameABDLPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABD));
Name nameABLPM("/a/b/hello/world");
temp = nt.findLongestPrefixMatch(nameABLPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAB));
Name nameAELPM("/a/e/hello/world");
temp = nt.findLongestPrefixMatch(nameAELPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAE));
Name nameALPM("/a/hello/world");
temp = nt.findLongestPrefixMatch(nameALPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameA));
Name nameFLPM("/f/hello/world");
temp = nt.findLongestPrefixMatch(nameFLPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameF));
Name nameRootLPM("/does_not_exist");
temp = nt.findLongestPrefixMatch(nameRootLPM);
BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));
// nt.dump(std::cout);
bool eraseResult = false;
temp = nt.findExactMatch(nameABC);
if (static_cast<bool>(temp))
eraseResult = nt.
eraseEntryIfEmpty(temp);
BOOST_CHECK_EQUAL(nt.size(), 6);
BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
BOOST_CHECK_EQUAL(eraseResult, true);
eraseResult = false;
temp = nt.findExactMatch(nameABCLPM);
if (static_cast<bool>(temp))
eraseResult = nt.
eraseEntryIfEmpty(temp);
BOOST_CHECK(!static_cast<bool>(temp));
BOOST_CHECK_EQUAL(nt.size(), 6);
BOOST_CHECK_EQUAL(eraseResult, false);
// nt.dump(std::cout);
nt.lookup(nameABC);
BOOST_CHECK_EQUAL(nt.size(), 7);
eraseResult = false;
temp = nt.findExactMatch(nameABC);
if (static_cast<bool>(temp))
eraseResult = nt.
eraseEntryIfEmpty(temp);
BOOST_CHECK_EQUAL(nt.size(), 6);
BOOST_CHECK_EQUAL(eraseResult, true);
BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
// nt.dump(std::cout);
BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);
// should resize now
Name nameABCD("a/b/c/d");
nt.lookup(nameABCD);
Name nameABCDE("a/b/c/d/e");
nt.lookup(nameABCDE);
BOOST_CHECK_EQUAL(nt.size(), 9);
BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);
// nt.dump(std::cout);
// try to erase /a/b/c, should return false
temp = nt.findExactMatch(nameABC);
BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
eraseResult = nt.
eraseEntryIfEmpty(temp);
BOOST_CHECK_EQUAL(eraseResult, false);
temp = nt.findExactMatch(nameABC);
BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
temp = nt.findExactMatch(nameABD);
if (static_cast<bool>(temp))
nt.
eraseEntryIfEmpty(temp);
BOOST_CHECK_EQUAL(nt.size(), 8);
// nt.dump(std::cout);
shared_ptr<std::vector<shared_ptr<name_tree::Entry> > > fullList;
fullList = nt.fullEnumerate();
BOOST_CHECK_EQUAL(fullList->size(), 8);
// for (size_t j = 0; j < (*fullList).size(); j++)
// {
// temp = (*fullList)[j];
// std::cout << temp->getPrefix().toUri() << std::endl;
// }
shared_ptr<std::vector<shared_ptr<name_tree::Entry> > > partialList;
partialList = nt.partialEnumerate(nameA);
BOOST_CHECK_EQUAL(partialList->size(), 6);
// for (size_t j = 0; j < (*partialList).size(); j++)
// {
// temp = (*partialList)[j];
// std::cout << temp->getPrefix().toUri() << std::endl;
// }
partialList = nt.partialEnumerate(nameRoot);
BOOST_CHECK_EQUAL(partialList->size(), 8);
// for (size_t j = 0; j < (*partialList).size(); j++)
// {
// temp = (*partialList)[j];
// std::cout << temp->getPrefix().toUri() << std::endl;
// }
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace nfd