fw: remove ncc strategy

Change-Id: I6de0acf51e965afcbda5cc943cb39daa78cabf2d
diff --git a/daemon/fw/ncc-strategy.cpp b/daemon/fw/ncc-strategy.cpp
deleted file mode 100644
index 060821a..0000000
--- a/daemon/fw/ncc-strategy.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2020,  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,
- *                           The University of Memphis.
- *
- * 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 "ncc-strategy.hpp"
-#include "algorithm.hpp"
-#include "common/global.hpp"
-
-#include <ndn-cxx/util/random.hpp>
-
-namespace nfd {
-namespace fw {
-
-NFD_REGISTER_STRATEGY(NccStrategy);
-
-const time::microseconds NccStrategy::DEFER_FIRST_WITHOUT_BEST_FACE = 4_ms;
-const time::microseconds NccStrategy::DEFER_RANGE_WITHOUT_BEST_FACE = 75_ms;
-const time::nanoseconds NccStrategy::MEASUREMENTS_LIFETIME = 16_s;
-
-NccStrategy::NccStrategy(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder)
-{
-  ParsedInstanceName parsed = parseInstanceName(name);
-  if (!parsed.parameters.empty()) {
-    NDN_THROW(std::invalid_argument("NccStrategy does not accept parameters"));
-  }
-  if (parsed.version && *parsed.version != getStrategyName()[-1].toVersion()) {
-    NDN_THROW(std::invalid_argument(
-      "NccStrategy does not support version " + to_string(*parsed.version)));
-  }
-  this->setInstanceName(makeInstanceName(name, getStrategyName()));
-}
-
-const Name&
-NccStrategy::getStrategyName()
-{
-  static Name strategyName("/localhost/nfd/strategy/ncc/%FD%01");
-  return strategyName;
-}
-
-void
-NccStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
-                                  const shared_ptr<pit::Entry>& pitEntry)
-{
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
-  const fib::NextHopList& nexthops = fibEntry.getNextHops();
-  if (nexthops.size() == 0) {
-    this->rejectPendingInterest(pitEntry);
-    return;
-  }
-
-  PitEntryInfo* pitEntryInfo = pitEntry->insertStrategyInfo<PitEntryInfo>().first;
-  bool isNewPitEntry = !hasPendingOutRecords(*pitEntry);
-  if (!isNewPitEntry) {
-    return;
-  }
-
-  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-
-  time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
-  time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
-  size_t nUpstreams = nexthops.size();
-
-  shared_ptr<Face> bestFace = meInfo.getBestFace();
-  if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace) &&
-      !wouldViolateScope(ingress.face, interest, *bestFace) &&
-      canForwardToLegacy(*pitEntry, *bestFace)) {
-    // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
-    deferFirst = meInfo.prediction;
-    deferRange = time::microseconds((deferFirst.count() + 1) / 2);
-    --nUpstreams;
-    this->sendInterest(pitEntry, *bestFace, interest);
-    pitEntryInfo->bestFaceTimeout = getScheduler().schedule(meInfo.prediction,
-      bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
-  }
-  else {
-    // use first eligible nexthop
-    auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
-        [&] (const fib::NextHop& nexthop) {
-          Face& outFace = nexthop.getFace();
-          return !wouldViolateScope(ingress.face, interest, outFace) &&
-                 canForwardToLegacy(*pitEntry, outFace);
-        });
-    if (firstEligibleNexthop != nexthops.end()) {
-      this->sendInterest(pitEntry, firstEligibleNexthop->getFace(), interest);
-    }
-    else {
-      this->rejectPendingInterest(pitEntry);
-      return;
-    }
-  }
-
-  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
-  if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
-      !wouldViolateScope(ingress.face, interest, *previousFace) &&
-      canForwardToLegacy(*pitEntry, *previousFace)) {
-    --nUpstreams;
-  }
-
-  if (nUpstreams > 0) {
-    pitEntryInfo->maxInterval = std::max(1_us,
-      time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
-  }
-  else {
-    // Normally, maxInterval is unused if there aren't any face beyond best and previousBest.
-    // However, in case FIB entry gains a new nexthop before doPropagate executes (bug 1853),
-    // this maxInterval would be used to determine when the next doPropagate would happen.
-    pitEntryInfo->maxInterval = deferFirst;
-  }
-  pitEntryInfo->propagateTimer = getScheduler().schedule(deferFirst,
-    bind(&NccStrategy::doPropagate, this, ingress.face.getId(), weak_ptr<pit::Entry>(pitEntry)));
-}
-
-void
-NccStrategy::doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak)
-{
-  Face* inFace = this->getFace(inFaceId);
-  if (inFace == nullptr) {
-    return;
-  }
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (pitEntry == nullptr) {
-    return;
-  }
-  auto inRecord = pitEntry->getInRecord(*inFace);
-  if (inRecord == pitEntry->in_end()) {
-    return;
-  }
-  const Interest& interest = inRecord->getInterest();
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
-
-  PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  // pitEntryInfo is guaranteed to exist here, because doPropagate is triggered
-  // from a timer set by NccStrategy.
-  BOOST_ASSERT(pitEntryInfo != nullptr);
-
-  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-
-  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
-  if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
-      !wouldViolateScope(*inFace, interest, *previousFace) &&
-      canForwardToLegacy(*pitEntry, *previousFace)) {
-    this->sendInterest(pitEntry, *previousFace, interest);
-  }
-
-  bool isForwarded = false;
-  for (const auto& nexthop : fibEntry.getNextHops()) {
-    Face& face = nexthop.getFace();
-    if (!wouldViolateScope(*inFace, interest, face) &&
-        canForwardToLegacy(*pitEntry, face)) {
-      isForwarded = true;
-      this->sendInterest(pitEntry, face, interest);
-      break;
-    }
-  }
-
-  if (isForwarded) {
-    std::uniform_int_distribution<time::nanoseconds::rep> dist(0, pitEntryInfo->maxInterval.count() - 1);
-    time::nanoseconds deferNext(dist(ndn::random::getRandomNumberEngine()));
-    pitEntryInfo->propagateTimer = getScheduler().schedule(deferNext,
-      bind(&NccStrategy::doPropagate, this, inFaceId, weak_ptr<pit::Entry>(pitEntry)));
-  }
-}
-
-void
-NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
-{
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (pitEntry == nullptr) {
-    return;
-  }
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (measurementsEntry == nullptr) {
-      // going out of this strategy's namespace
-      break;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
-    meInfo.adjustPredictUp();
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-}
-
-void
-NccStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
-                                   const FaceEndpoint& ingress, const Data& data)
-{
-  if (!pitEntry->hasInRecords()) {
-    // PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
-    // NCC does not collect measurements for non-best face
-    return;
-  }
-
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (measurementsEntry == nullptr) {
-      // going out of this strategy's namespace
-      return;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
-    meInfo.updateBestFace(ingress.face);
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-
-  PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  if (pitEntryInfo != nullptr) {
-    pitEntryInfo->propagateTimer.cancel();
-
-    // Verify that the best face satisfied the interest before canceling the timeout call
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-    shared_ptr<Face> bestFace = meInfo.getBestFace();
-
-    if (bestFace.get() == &ingress.face)
-      pitEntryInfo->bestFaceTimeout.cancel();
-  }
-}
-
-NccStrategy::MeasurementsEntryInfo&
-NccStrategy::getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry)
-{
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*entry);
-  return this->getMeasurementsEntryInfo(measurementsEntry);
-}
-
-NccStrategy::MeasurementsEntryInfo&
-NccStrategy::getMeasurementsEntryInfo(measurements::Entry* entry)
-{
-  BOOST_ASSERT(entry != nullptr);
-  MeasurementsEntryInfo* info = nullptr;
-  bool isNew = false;
-  std::tie(info, isNew) = entry->insertStrategyInfo<MeasurementsEntryInfo>();
-  if (!isNew) {
-    return *info;
-  }
-
-  measurements::Entry* parentEntry = this->getMeasurements().getParent(*entry);
-  if (parentEntry != nullptr) {
-    MeasurementsEntryInfo& parentInfo = this->getMeasurementsEntryInfo(parentEntry);
-    info->inheritFrom(parentInfo);
-  }
-
-  return *info;
-}
-
-const time::microseconds NccStrategy::MeasurementsEntryInfo::INITIAL_PREDICTION = 8192_us;
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MIN_PREDICTION = 127_us;
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MAX_PREDICTION = 160_ms;
-
-NccStrategy::MeasurementsEntryInfo::MeasurementsEntryInfo()
-  : prediction(INITIAL_PREDICTION)
-{
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::inheritFrom(const MeasurementsEntryInfo& other)
-{
-  this->operator=(other);
-}
-
-shared_ptr<Face>
-NccStrategy::MeasurementsEntryInfo::getBestFace()
-{
-  shared_ptr<Face> best = this->bestFace.lock();
-  if (best != nullptr) {
-    return best;
-  }
-  this->bestFace = best = this->previousFace.lock();
-  return best;
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::updateBestFace(const Face& face)
-{
-  if (this->bestFace.expired()) {
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-    return;
-  }
-  shared_ptr<Face> bestFace = this->bestFace.lock();
-  if (bestFace.get() == &face) {
-    this->adjustPredictDown();
-  }
-  else {
-    this->previousFace = this->bestFace;
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-  }
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictDown()
-{
-  prediction = std::max(MIN_PREDICTION,
-    time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictUp()
-{
-  prediction = std::min(MAX_PREDICTION,
-    time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::ageBestFace()
-{
-  this->previousFace = this->bestFace;
-  this->bestFace.reset();
-}
-
-NccStrategy::PitEntryInfo::~PitEntryInfo()
-{
-  bestFaceTimeout.cancel();
-  propagateTimer.cancel();
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/daemon/fw/ncc-strategy.hpp b/daemon/fw/ncc-strategy.hpp
deleted file mode 100644
index 3ba5019..0000000
--- a/daemon/fw/ncc-strategy.hpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2021,  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,
- *                           The University of Memphis.
- *
- * 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/>.
- */
-
-#ifndef NFD_DAEMON_FW_NCC_STRATEGY_HPP
-#define NFD_DAEMON_FW_NCC_STRATEGY_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief A forwarding strategy similar to CCNx 0.7.2
- */
-class NccStrategy : public Strategy
-{
-public:
-  explicit
-  NccStrategy(Forwarder& forwarder, const Name& name = getStrategyName());
-
-  static const Name&
-  getStrategyName();
-
-  void
-  afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
-                       const shared_ptr<pit::Entry>& pitEntry) override;
-
-  void
-  beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
-                        const FaceEndpoint& ingress, const Data& data) override;
-
-NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  /// StrategyInfo on measurements::Entry
-  class MeasurementsEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1000;
-    }
-
-    MeasurementsEntryInfo();
-
-    void
-    inheritFrom(const MeasurementsEntryInfo& other);
-
-    shared_ptr<Face>
-    getBestFace();
-
-    void
-    updateBestFace(const Face& face);
-
-    void
-    adjustPredictUp();
-
-  private:
-    void
-    adjustPredictDown();
-
-    void
-    ageBestFace();
-
-  public:
-    weak_ptr<Face> bestFace;
-    weak_ptr<Face> previousFace;
-    time::microseconds prediction;
-
-    static const time::microseconds INITIAL_PREDICTION;
-    static const time::microseconds MIN_PREDICTION;
-    static const int ADJUST_PREDICT_DOWN_SHIFT = 7;
-    static const time::microseconds MAX_PREDICTION;
-    static const int ADJUST_PREDICT_UP_SHIFT = 3;
-  };
-
-  /// StrategyInfo on pit::Entry
-  class PitEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1001;
-    }
-
-    ~PitEntryInfo() override;
-
-  public:
-    /// timer that expires when best face does not respond within predicted time
-    scheduler::EventId bestFaceTimeout;
-    /// timer for propagating to another face
-    scheduler::EventId propagateTimer;
-    /// maximum interval between forwarding to two nexthops except best and previous
-    time::microseconds maxInterval;
-  };
-
-protected:
-  MeasurementsEntryInfo&
-  getMeasurementsEntryInfo(measurements::Entry* entry);
-
-  MeasurementsEntryInfo&
-  getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry);
-
-  /// propagate to another upstream
-  void
-  doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak);
-
-  /// best face did not reply within prediction
-  void
-  timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak);
-
-protected:
-  static const time::microseconds DEFER_FIRST_WITHOUT_BEST_FACE;
-  static const time::microseconds DEFER_RANGE_WITHOUT_BEST_FACE;
-  static const int UPDATE_MEASUREMENTS_N_LEVELS = 2;
-  static const time::nanoseconds MEASUREMENTS_LIFETIME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_NCC_STRATEGY_HPP
diff --git a/tests/daemon/fw/ncc-strategy.t.cpp b/tests/daemon/fw/ncc-strategy.t.cpp
deleted file mode 100644
index 3c3f4d4..0000000
--- a/tests/daemon/fw/ncc-strategy.t.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2019,  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,
- *                           The University of Memphis.
- *
- * 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 "fw/ncc-strategy.hpp"
-
-#include "tests/daemon/face/dummy-face.hpp"
-#include "strategy-tester.hpp"
-#include "topology-tester.hpp"
-
-namespace nfd {
-namespace fw {
-namespace tests {
-
-using NccStrategyTester = StrategyTester<NccStrategy>;
-NFD_REGISTER_STRATEGY(NccStrategyTester);
-
-BOOST_AUTO_TEST_SUITE(Fw)
-BOOST_FIXTURE_TEST_SUITE(TestNccStrategy, GlobalIoTimeFixture)
-
-BOOST_AUTO_TEST_CASE(FavorRespondingUpstream)
-{
-  // NccStrategy is fairly complex.
-  // The most important property is: it remembers which upstream is the fastest to return Data,
-  // and favors this upstream in subsequent Interests.
-
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy knows nothing and follows routing
-  shared_ptr<Interest> interest1p = makeInterest("ndn:/0Jm1ajrW/%00");
-  Interest& interest1 = *interest1p;
-  interest1.setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), interest1, pitEntry1);
-
-  // forwards to face1 because routing says it's best
-  // (no io run here: afterReceiveInterest has already sent the Interest)
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-
-  // forwards to face2 because face1 doesn't respond
-  limitedIo.run(1, 500_ms, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-
-  // face2 responds
-  shared_ptr<Data> data1p = makeData("ndn:/0Jm1ajrW/%00");
-  Data& data1 = *data1p;
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), data1);
-  this->advanceClocks(10_ms, 500_ms);
-
-  // second Interest: strategy knows face2 is best
-  shared_ptr<Interest> interest2p = makeInterest("ndn:/0Jm1ajrW/%00%01");
-  Interest& interest2 = *interest2p;
-  interest2.setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), interest2, pitEntry2);
-
-  // forwards to face2 because it responds previously
-  this->advanceClocks(1_ms);
-  BOOST_REQUIRE_GE(strategy.sendInterestHistory.size(), 3);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[2].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1853)
-{
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy follows routing and forwards to face1
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/nztwIvHX/%00");
-  interest1->setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest1, pitEntry1);
-
-  this->advanceClocks(1_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-
-  // face1 responds
-  shared_ptr<Data> data1 = makeData("ndn:/nztwIvHX/%00");
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face1, 0), *data1);
-  this->advanceClocks(10_ms, 500_ms);
-
-  // second Interest: bestFace is face1, nUpstreams becomes 0,
-  // therefore pitEntryInfo->maxInterval cannot be calculated from deferRange and nUpstreams
-  shared_ptr<Interest> interest2 = makeInterest("ndn:/nztwIvHX/%01");
-  interest2->setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(*interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, *interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest2, pitEntry2);
-
-  // FIB entry is changed before doPropagate executes
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-  this->advanceClocks(10_ms, 1_s);// should not crash
-}
-
-BOOST_AUTO_TEST_CASE(Bug1961)
-{
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy forwards to face1 and face2
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/seRMz5a6/%00");
-  interest1->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest1, pitEntry1);
-  limitedIo.run(2 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-
-  // face1 responds
-  shared_ptr<Data> data1 = makeData("ndn:/seRMz5a6/%00");
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face1, 0), *data1);
-  pitEntry1->clearInRecords();
-  this->advanceClocks(10_ms);
-  // face2 also responds
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), *data1);
-  this->advanceClocks(10_ms);
-
-  // second Interest: bestFace should be face 1
-  shared_ptr<Interest> interest2 = makeInterest("ndn:/seRMz5a6/%01");
-  interest2->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(*interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, *interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest2, pitEntry2);
-  limitedIo.run(3 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-
-  BOOST_REQUIRE_GE(strategy.sendInterestHistory.size(), 3);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[2].outFaceId, face1->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1971)
-{
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face2, 10);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy forwards to face2
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/M4mBXCsd");
-  interest1->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-  limitedIo.run(1 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face2->getId());
-
-  // face2 responds
-  shared_ptr<Data> data1 = makeData("ndn:/M4mBXCsd");
-  data1->setFreshnessPeriod(5_ms);
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), *data1);
-  pitEntry1->deleteOutRecord(*face2);
-  pitEntry1->clearInRecords();
-  this->advanceClocks(10_ms);
-
-  // similar Interest: strategy should still forward it
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-  limitedIo.run(2 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1998)
-{
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10); // face1 is top-ranked nexthop
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // Interest comes from face1, which is sole downstream
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/tFy5HzUzD4");
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-
-  // Interest shall go to face2, not loop back to face1
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(PredictionAdjustment, 1)
-BOOST_AUTO_TEST_CASE(PredictionAdjustment) // Bug 3411
-{
-  /*
-   * /----------\
-   * | consumer |
-   * \----------/
-   *     |
-   *     |
-   *   +---+  5ms  +---+
-   *   | A |-------| B |
-   *   +---+       +---+
-   *     |           |
-   *     | 5ms       | 15ms/5ms
-   *     |           |
-   *   +---+       +---+
-   *   | C |-------| D |
-   *   +---+ 15ms  +---+
-   *         /5ms    |
-   *                 |
-   *         /----------\
-   *         | producer |
-   *         \----------/
-   */
-
-  TopologyTester topo;
-  TopologyNode nodeA = topo.addForwarder("A"),
-               nodeB = topo.addForwarder("B"),
-               nodeC = topo.addForwarder("C"),
-               nodeD = topo.addForwarder("D");
-
-  for (TopologyNode node : {nodeA, nodeB, nodeC, nodeD}) {
-    topo.setStrategy<NccStrategy>(node);
-  }
-
-  shared_ptr<TopologyLink> linkAB = topo.addLink("AB", 5_ms, {nodeA, nodeB}),
-                           linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeC}),
-                           linkBD = topo.addLink("BD", 15_ms, {nodeB, nodeD}),
-                           linkCD = topo.addLink("CD", 15_ms, {nodeC, nodeD});
-
-  topo.registerPrefix(nodeA, linkAB->getFace(nodeA), "ndn:/P");
-  topo.registerPrefix(nodeA, linkAC->getFace(nodeA), "ndn:/P");
-  topo.registerPrefix(nodeB, linkBD->getFace(nodeB), "ndn:/P");
-  topo.registerPrefix(nodeC, linkCD->getFace(nodeC), "ndn:/P");
-
-  shared_ptr<TopologyAppLink> producer = topo.addAppFace("producer", nodeD, "ndn:/P");
-  topo.addEchoProducer(producer->getClientFace());
-
-  shared_ptr<TopologyAppLink> consumer = topo.addAppFace("consumer", nodeA);
-  topo.addIntervalConsumer(consumer->getClientFace(), "ndn:/P",
-                           100_ms, 300);
-
-  auto getMeInfo = [&] () -> NccStrategy::MeasurementsEntryInfo* {
-    Measurements& measurements = topo.getForwarder(nodeA).getMeasurements();
-    measurements::Entry* me = measurements.findExactMatch("ndn:/P");
-    return me == nullptr ? nullptr : me->getStrategyInfo<NccStrategy::MeasurementsEntryInfo>();
-  };
-
-  // NccStrategy starts with an exploration period when the algorithm adjusts
-  // its prediction to converge near the path RTT.
-  bool isExplorationFinished = false;
-  const time::milliseconds TRUE_RTT1(40);
-  bool isLastPredictionUnder = true;
-  int nPredictionCrossings = 0;
-  for (int i = 0; i < 10000; ++i) {
-    this->advanceClocks(5_ms);
-    auto meInfo = getMeInfo();
-    if (meInfo == nullptr) {
-      continue;
-    }
-
-    if ((isLastPredictionUnder && meInfo->prediction > TRUE_RTT1) ||
-        (!isLastPredictionUnder && meInfo->prediction < TRUE_RTT1)) {
-      isLastPredictionUnder = !isLastPredictionUnder;
-      if (++nPredictionCrossings > 6) {
-        isExplorationFinished = true;
-        BOOST_TEST_MESSAGE("exploration finishes after " << (i * 5) << "ms");
-        break;
-      }
-    }
-  }
-  BOOST_REQUIRE_MESSAGE(isExplorationFinished, "exploration did not finish within 50s");
-
-  // NccStrategy has selected one path as the best.
-  // When we reduce the RTT of the other path, ideally it should be selected as the best face.
-  // However, this won't happen due to a weakness in NccStrategy.
-  // See  https://redmine.named-data.net/issues/3411#note-4
-  shared_ptr<Face> bestFace1 = getMeInfo()->bestFace.lock();
-  if (bestFace1.get() == &linkAB->getFace(nodeA)) {
-    linkCD->setDelay(5_ms);
-  }
-  else if (bestFace1.get() == &linkAC->getFace(nodeA)) {
-    linkBD->setDelay(5_ms);
-  }
-  else {
-    BOOST_FAIL("unexpected best face");
-  }
-
-  bool isNewBestChosen = false;
-  for (int i = 0; i < 10000; ++i) {
-    this->advanceClocks(5_ms);
-    auto meInfo = getMeInfo();
-    if (meInfo == nullptr) {
-      continue;
-    }
-
-    if (meInfo->bestFace.lock() != bestFace1) {
-      isNewBestChosen = true;
-      BOOST_TEST_MESSAGE("new best face is found after " << (i * 5) << "ms");
-      break;
-    }
-  }
-  BOOST_CHECK_MESSAGE(isNewBestChosen, "new best face is not found in 50000ms"); // expected failure
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestNccStrategy
-BOOST_AUTO_TEST_SUITE_END() // Fw
-
-} // namespace tests
-} // namespace fw
-} // namespace nfd
diff --git a/tests/daemon/fw/strategy-instantiation.t.cpp b/tests/daemon/fw/strategy-instantiation.t.cpp
index 4ea9bb3..cd057bc 100644
--- a/tests/daemon/fw/strategy-instantiation.t.cpp
+++ b/tests/daemon/fw/strategy-instantiation.t.cpp
@@ -33,19 +33,17 @@
 #include "fw/best-route-strategy.hpp"
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
-#include "fw/ncc-strategy.hpp"
 #include "fw/self-learning-strategy.hpp"
 #include "fw/random-strategy.hpp"
 
 #include "tests/test-common.hpp"
+
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
 namespace fw {
 namespace tests {
 
-using namespace nfd::tests;
-
 BOOST_AUTO_TEST_SUITE(Fw)
 BOOST_AUTO_TEST_SUITE(TestStrategyInstantiation)
 
@@ -80,7 +78,6 @@
   Test<BestRouteStrategy, false, 1>,
   Test<BestRouteStrategy2, false, 5>,
   Test<MulticastStrategy, false, 4>,
-  Test<NccStrategy, false, 1>,
   Test<SelfLearningStrategy, false, 1>,
   Test<RandomStrategy, false, 1>
 >;
diff --git a/tests/daemon/fw/strategy-scope-control.t.cpp b/tests/daemon/fw/strategy-scope-control.t.cpp
index 123a4f8..a707a46 100644
--- a/tests/daemon/fw/strategy-scope-control.t.cpp
+++ b/tests/daemon/fw/strategy-scope-control.t.cpp
@@ -33,7 +33,6 @@
 #include "fw/best-route-strategy.hpp"
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
-#include "fw/ncc-strategy.hpp"
 #include "fw/random-strategy.hpp"
 
 #include "tests/test-common.hpp"
@@ -41,7 +40,6 @@
 #include "choose-strategy.hpp"
 #include "strategy-tester.hpp"
 
-#include <boost/mpl/copy_if.hpp>
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
@@ -87,7 +85,7 @@
 BOOST_AUTO_TEST_SUITE(Fw)
 BOOST_AUTO_TEST_SUITE(TestStrategyScopeControl)
 
-template<typename S, bool WillSendNackNoRoute, bool CanProcessNack, bool WillRejectPitEntry = true>
+template<typename S, bool WillSendNackNoRoute, bool CanProcessNack, bool WillRejectPitEntry>
 class Test
 {
 public:
@@ -113,13 +111,12 @@
 };
 
 using Tests = boost::mpl::vector<
-  Test<AccessStrategy, false, false>,
-  Test<AsfStrategy, true, false>,
-  Test<BestRouteStrategy, false, false>,
-  Test<BestRouteStrategy2, true, true>,
+  Test<AccessStrategy, false, false, true>,
+  Test<AsfStrategy, true, false, true>,
+  Test<BestRouteStrategy, false, false, true>,
+  Test<BestRouteStrategy2, true, true, true>,
   Test<MulticastStrategy, false, false, false>,
-  Test<NccStrategy, false, false>,
-  Test<RandomStrategy, true, true>
+  Test<RandomStrategy, true, true, true>
 >;
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostInterestToLocal,
@@ -259,7 +256,7 @@
   this->fib.addOrUpdateNextHop(*fibEntry, *this->localFace4, 10);
   this->fib.addOrUpdateNextHop(*fibEntry, *this->nonLocalFace2, 20);
 
-  auto interest = makeInterest("/localhop/A/1", 1377);
+  auto interest = makeInterest("/localhop/A/1", false, nullopt, 1377);
   shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
   pitEntry->insertOrUpdateInRecord(*this->nonLocalFace1, *interest);
   lp::Nack nack = makeNack(*interest, lp::NackReason::NO_ROUTE);