fw: introduce afterContentStoreHit strategy trigger

Change-Id: I71ca9e21467d2296203eb9686bff7647b1140271
refs: #4290
diff --git a/tests/daemon/fw/dummy-strategy.cpp b/tests/daemon/fw/dummy-strategy.cpp
index 28ca606..b37171f 100644
--- a/tests/daemon/fw/dummy-strategy.cpp
+++ b/tests/daemon/fw/dummy-strategy.cpp
@@ -46,6 +46,7 @@
   : Strategy(forwarder)
   , afterReceiveInterest_count(0)
   , beforeSatisfyInterest_count(0)
+  , afterContentStoreHit_count(0)
   , afterReceiveNack_count(0)
 {
   this->setInstanceName(name);
@@ -73,6 +74,15 @@
 }
 
 void
+DummyStrategy::afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
+                                    const Face& inFace, const Data& data)
+{
+  ++afterContentStoreHit_count;
+
+  this->sendData(pitEntry, data, inFace);
+}
+
+void
 DummyStrategy::afterReceiveNack(const Face& inFace, const lp::Nack& nack,
                                 const shared_ptr<pit::Entry>& pitEntry)
 {
diff --git a/tests/daemon/fw/dummy-strategy.hpp b/tests/daemon/fw/dummy-strategy.hpp
index 1f168c5..24a432c 100644
--- a/tests/daemon/fw/dummy-strategy.hpp
+++ b/tests/daemon/fw/dummy-strategy.hpp
@@ -69,6 +69,10 @@
                         const Face& inFace, const Data& data) override;
 
   void
+  afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
+                       const Face& inFace, const Data& data) override;
+
+  void
   afterReceiveNack(const Face& inFace, const lp::Nack& nack,
                    const shared_ptr<pit::Entry>& pitEntry) override;
 
@@ -88,6 +92,7 @@
 public:
   int afterReceiveInterest_count;
   int beforeSatisfyInterest_count;
+  int afterContentStoreHit_count;
   int afterReceiveNack_count;
 
   shared_ptr<Face> interestOutFace;
diff --git a/tests/daemon/fw/pit-expiry.t.cpp b/tests/daemon/fw/pit-expiry.t.cpp
index 4eacd9e..1977458 100644
--- a/tests/daemon/fw/pit-expiry.t.cpp
+++ b/tests/daemon/fw/pit-expiry.t.cpp
@@ -29,6 +29,8 @@
 
 #include "tests/test-common.hpp"
 
+#include <ndn-cxx/lp/tags.hpp>
+
 namespace nfd {
 namespace fw {
 namespace tests {
@@ -63,7 +65,7 @@
   afterReceiveInterest(const Face& inFace, const Interest& interest,
                        const shared_ptr<pit::Entry>& pitEntry) override
   {
-    ++afterReceiveInterest_count;
+    DummyStrategy::afterReceiveInterest(inFace, interest, pitEntry);
 
     if (afterReceiveInterest_count <= 1) {
       setExpiryTimer(pitEntry, 190_ms);
@@ -74,18 +76,29 @@
   beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
                         const Face& inFace, const Data& data) override
   {
-    ++beforeSatisfyInterest_count;
+    DummyStrategy::beforeSatisfyInterest(pitEntry, inFace, data);
 
-    if (beforeSatisfyInterest_count <= 1 ) {
+    if (beforeSatisfyInterest_count <= 1) {
       setExpiryTimer(pitEntry, 190_ms);
     }
   }
 
   void
+  afterContentStoreHit(const shared_ptr<pit::Entry>& pitEntry,
+                       const Face& inFace, const Data& data) override
+  {
+    if (afterContentStoreHit_count == 0) {
+      setExpiryTimer(pitEntry, 190_ms);
+    }
+
+    DummyStrategy::afterContentStoreHit(pitEntry, inFace, data);
+  }
+
+  void
   afterReceiveNack(const Face& inFace, const lp::Nack& nack,
                    const shared_ptr<pit::Entry>& pitEntry) override
   {
-    ++afterReceiveNack_count;
+    DummyStrategy::afterReceiveNack(inFace, nack, pitEntry);
 
     if (afterReceiveNack_count <= 1) {
       setExpiryTimer(pitEntry, 50_ms);
@@ -141,6 +154,43 @@
   BOOST_CHECK_EQUAL(pit.size(), 0);
 }
 
+BOOST_AUTO_TEST_CASE(CsHit)
+{
+  Forwarder forwarder;
+
+  auto face1 = make_shared<DummyFace>();
+  auto face2 = make_shared<DummyFace>();
+  forwarder.addFace(face1);
+  forwarder.addFace(face2);
+
+  Name strategyA("/strategyA/%FD%01");
+  PitExpiryTestStrategy::registerAs(strategyA);
+  choose<PitExpiryTestStrategy>(forwarder, "/A", strategyA);
+
+  shared_ptr<Interest> interest = makeInterest("/A/0");
+  interest->setInterestLifetime(90_ms);
+
+  shared_ptr<Data> data = makeData("/A/0");
+  data->setTag(make_shared<lp::IncomingFaceIdTag>(face2->getId()));
+
+  Pit& pit = forwarder.getPit();
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+
+  Cs& cs = forwarder.getCs();
+  cs.insert(*data);
+
+  face1->receiveInterest(*interest);
+  this->advanceClocks(1_ms);
+  BOOST_CHECK_EQUAL(pit.size(), 1);
+
+  this->advanceClocks(190_ms);
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+
+  face1->receiveInterest(*interest);
+  this->advanceClocks(1_ms);
+  BOOST_CHECK_EQUAL(pit.size(), 0);
+}
+
 BOOST_AUTO_TEST_CASE(ReceiveNack)
 {
   Forwarder forwarder;