table: fix PIT not matching full name

refs #3363

Change-Id: I4ff3d02aaf43c3aaba843cfcf6221c218c1cea99
diff --git a/tests/daemon/table/fib.t.cpp b/tests/daemon/table/fib.t.cpp
index 59a88e9..30846f4 100644
--- a/tests/daemon/table/fib.t.cpp
+++ b/tests/daemon/table/fib.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,8 @@
  */
 
 #include "table/fib.hpp"
+#include "table/pit.hpp"
+#include "table/measurements.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
 
 #include "tests/test-common.hpp"
@@ -31,7 +33,8 @@
 namespace nfd {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TableFib, BaseFixture)
+BOOST_AUTO_TEST_SUITE(Table)
+BOOST_FIXTURE_TEST_SUITE(TestFib, BaseFixture)
 
 BOOST_AUTO_TEST_CASE(Entry)
 {
@@ -66,14 +69,14 @@
   BOOST_CHECK_EQUAL(nexthops4.size(), 2);
   int i = -1;
   for (fib::NextHopList::const_iterator it = nexthops4.begin();
-    it != nexthops4.end(); ++it) {
+       it != nexthops4.end(); ++it) {
     ++i;
     switch (i) {
-      case 0 :
+      case 0:
         BOOST_CHECK_EQUAL(it->getFace(), face1);
         BOOST_CHECK_EQUAL(it->getCost(), 30);
         break;
-      case 1 :
+      case 1:
         BOOST_CHECK_EQUAL(it->getFace(), face2);
         BOOST_CHECK_EQUAL(it->getCost(), 40);
         break;
@@ -86,14 +89,14 @@
   BOOST_CHECK_EQUAL(nexthops5.size(), 2);
   i = -1;
   for (fib::NextHopList::const_iterator it = nexthops5.begin();
-    it != nexthops5.end(); ++it) {
+       it != nexthops5.end(); ++it) {
     ++i;
     switch (i) {
-      case 0 :
+      case 0:
         BOOST_CHECK_EQUAL(it->getFace(), face2);
         BOOST_CHECK_EQUAL(it->getCost(), 10);
         break;
-      case 1 :
+      case 1:
         BOOST_CHECK_EQUAL(it->getFace(), face1);
         BOOST_CHECK_EQUAL(it->getCost(), 30);
         break;
@@ -198,6 +201,64 @@
   BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
 }
 
+BOOST_AUTO_TEST_CASE(LongestPrefixMatchWithPitEntry)
+{
+  NameTree nameTree;
+  Fib fib(nameTree);
+
+  shared_ptr<Data> dataABC = makeData("/A/B/C");
+  Name fullNameABC = dataABC->getFullName();
+  shared_ptr<Data> dataADE = makeData("/A/D/E");
+  Name fullNameADE = dataADE->getFullName();
+  fib.insert("/A");
+  fib.insert(fullNameABC);
+
+  Pit pit(nameTree);
+  shared_ptr<Interest> interestAB = makeInterest("/A/B");
+  shared_ptr<pit::Entry> pitAB = pit.insert(*interestAB).first;
+  shared_ptr<Interest> interestABC = makeInterest(fullNameABC);
+  shared_ptr<pit::Entry> pitABC = pit.insert(*interestABC).first;
+  shared_ptr<Interest> interestADE = makeInterest(fullNameADE);
+  shared_ptr<pit::Entry> pitADE = pit.insert(*interestADE).first;
+
+  size_t nNameTreeEntries = nameTree.size();
+
+  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(*pitAB);
+  BOOST_REQUIRE(entry != nullptr);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+  entry = fib.findLongestPrefixMatch(*pitABC);
+  BOOST_REQUIRE(entry != nullptr);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), fullNameABC);
+
+  entry = fib.findLongestPrefixMatch(*pitADE);
+  BOOST_REQUIRE(entry != nullptr);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+  BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntries);
+}
+
+BOOST_AUTO_TEST_CASE(LongestPrefixMatchWithMeasurementsEntry)
+{
+  NameTree nameTree;
+  Fib fib(nameTree);
+
+  fib.insert("/A");
+  fib.insert("/A/B/C");
+
+  Measurements measurements(nameTree);
+  shared_ptr<measurements::Entry> mAB = measurements.get("/A/B");
+  shared_ptr<measurements::Entry> mABCD = measurements.get("/A/B/C/D");
+
+  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(*mAB);
+  BOOST_REQUIRE(entry != nullptr);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+  entry = fib.findLongestPrefixMatch(*mABCD);
+  BOOST_REQUIRE(entry != nullptr);
+  BOOST_CHECK_EQUAL(entry->getPrefix(), "/A/B/C");
+}
+
 BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
 {
   shared_ptr<Face> face1 = make_shared<DummyFace>();
@@ -420,8 +481,7 @@
   expected.insert(nameABC);
   expected.insert(nameRoot);
 
-  for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
-  {
+  for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++) {
     bool isInSet = expected.find(it->getPrefix()) != expected.end();
     BOOST_CHECK(isInSet);
     expected.erase(it->getPrefix());
@@ -430,7 +490,8 @@
   BOOST_CHECK_EQUAL(expected.size(), 0);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestFib
+BOOST_AUTO_TEST_SUITE_END() // Table
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/table/measurements.t.cpp b/tests/daemon/table/measurements.t.cpp
index 0f788bb..bbf1903 100644
--- a/tests/daemon/table/measurements.t.cpp
+++ b/tests/daemon/table/measurements.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -99,10 +99,18 @@
 
   shared_ptr<Interest> interestA = makeInterest("/A");
   shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
+  shared_ptr<Data> dataABC = makeData("/A/B/C");
+  Name fullName = dataABC->getFullName();
+  shared_ptr<Interest> interestFull = makeInterest(fullName);
+  shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;
 
   shared_ptr<measurements::Entry> entryA = measurements.get(*pitA);
   BOOST_REQUIRE(entryA != nullptr);
   BOOST_CHECK_EQUAL(entryA->getName(), "/A");
+
+  shared_ptr<measurements::Entry> entryFull = measurements.get(*pitFull);
+  BOOST_REQUIRE(entryFull != nullptr);
+  BOOST_CHECK_EQUAL(entryFull->getName(), fullName);
 }
 
 class DummyStrategyInfo1 : public fw::StrategyInfo
diff --git a/tests/daemon/table/pit.t.cpp b/tests/daemon/table/pit.t.cpp
index dd02bec..546c0a5 100644
--- a/tests/daemon/table/pit.t.cpp
+++ b/tests/daemon/table/pit.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -487,7 +487,23 @@
   BOOST_CHECK_EQUAL(hasD  , false);
 
   BOOST_CHECK_EQUAL(count, 2);
+}
 
+BOOST_AUTO_TEST_CASE(MatchFullName) // Bug 3363
+{
+  NameTree nameTree(16);
+  Pit pit(nameTree);
+
+  shared_ptr<Data> data = makeData("/A");
+  Name fullName = data->getFullName();
+  shared_ptr<Interest> interest = makeInterest(fullName);
+
+  pit.insert(*interest);
+  pit::DataMatchResult matches = pit.findAllDataMatches(*data);
+
+  BOOST_REQUIRE_EQUAL(std::distance(matches.begin(), matches.end()), 1);
+  shared_ptr<pit::Entry> found = *matches.begin();
+  BOOST_CHECK_EQUAL(found->getName(), fullName);
 }
 
 BOOST_AUTO_TEST_CASE(Iterator)
diff --git a/tests/daemon/table/strategy-choice.t.cpp b/tests/daemon/table/strategy-choice.t.cpp
index ec450f5..469cb1a 100644
--- a/tests/daemon/table/strategy-choice.t.cpp
+++ b/tests/daemon/table/strategy-choice.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
 namespace nfd {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TableStrategyChoice, BaseFixture)
+BOOST_AUTO_TEST_SUITE(Table)
+BOOST_FIXTURE_TEST_SUITE(TestStrategyChoice, BaseFixture)
 
 using fw::Strategy;
 
@@ -57,7 +58,7 @@
   BOOST_CHECK_EQUAL(getA.first, false);
 }
 
-BOOST_AUTO_TEST_CASE(Effective)
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategy)
 {
   Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
@@ -124,13 +125,61 @@
   BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/D")  .getName(), nameQ);
 }
 
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithPitEntry)
+{
+  Forwarder forwarder;
+  Name nameP("ndn:/strategy/P");
+  Name nameQ("ndn:/strategy/Q");
+  shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(ref(forwarder), nameP);
+  shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(ref(forwarder), nameQ);
+  StrategyChoice& table = forwarder.getStrategyChoice();
+  table.install(strategyP);
+  table.install(strategyQ);
+
+  shared_ptr<Data> dataABC = makeData("/A/B/C");
+  Name fullName = dataABC->getFullName();
+
+  BOOST_CHECK(table.insert("/A", nameP));
+  BOOST_CHECK(table.insert(fullName, nameQ));
+
+  Pit& pit = forwarder.getPit();
+  shared_ptr<Interest> interestAB = makeInterest("/A/B");
+  shared_ptr<pit::Entry> pitAB = pit.insert(*interestAB).first;
+  shared_ptr<Interest> interestFull = makeInterest(fullName);
+  shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitAB).getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitFull).getName(), nameQ);
+}
+
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithMeasurementsEntry)
+{
+  Forwarder forwarder;
+  Name nameP("ndn:/strategy/P");
+  Name nameQ("ndn:/strategy/Q");
+  shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(ref(forwarder), nameP);
+  shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(ref(forwarder), nameQ);
+  StrategyChoice& table = forwarder.getStrategyChoice();
+  table.install(strategyP);
+  table.install(strategyQ);
+
+  BOOST_CHECK(table.insert("/A", nameP));
+  BOOST_CHECK(table.insert("/A/B/C", nameQ));
+
+  Measurements& measurements = forwarder.getMeasurements();
+  shared_ptr<measurements::Entry> mAB = measurements.get("/A/B");
+  shared_ptr<measurements::Entry> mABCD = measurements.get("/A/B/C/D");
+
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*mAB).getName(), nameP);
+  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*mABCD).getName(), nameQ);
+}
+
 //XXX BOOST_CONCEPT_ASSERT((ForwardIterator<std::vector<int>::iterator>))
 //    is also failing. There might be a problem with ForwardIterator concept checking.
 //BOOST_CONCEPT_ASSERT((ForwardIterator<StrategyChoice::const_iterator>));
 
 BOOST_AUTO_TEST_CASE(Enumerate)
 {
-
   Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
@@ -305,7 +354,8 @@
   BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), name4);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoice
+BOOST_AUTO_TEST_SUITE_END() // Table
 
 } // namespace tests
 } // namespace nfd