/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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/asf-strategy.hpp"

#include "strategy-tester.hpp"
#include "topology-tester.hpp"

namespace nfd {
namespace fw {
namespace asf {
namespace tests {

using namespace nfd::fw::tests;

// The tester is unused in this file, but it's used in various templated test suites.
using AsfStrategyTester = StrategyTester<AsfStrategy>;
NFD_REGISTER_STRATEGY(AsfStrategyTester);

BOOST_AUTO_TEST_SUITE(Fw)
BOOST_FIXTURE_TEST_SUITE(TestAsfStrategy, GlobalIoTimeFixture)

class AsfGridFixture : public GlobalIoTimeFixture
{
protected:
  explicit
  AsfGridFixture(const Name& params = AsfStrategy::getStrategyName(),
                 time::nanoseconds replyDelay = 0_ns)
    : parameters(params)
  {
    /*
     *                  +---------+
     *           +----->|  nodeB  |<------+
     *           |      +---------+       |
     *      10ms |                        | 10ms
     *           v                        v
     *      +---------+              +---------+
     *      |  nodeA  |              |  nodeC  |
     *      +---------+              +---------+
     *           ^                        ^
     *     100ms |                        | 100ms
     *           |      +---------+       |
     *           +----->|  nodeD  |<------+
     *                  +---------+
     */

    nodeA = topo.addForwarder("A");
    nodeB = topo.addForwarder("B");
    nodeC = topo.addForwarder("C");
    nodeD = topo.addForwarder("D");

    for (auto node : {nodeA, nodeB, nodeC, nodeD}) {
      topo.setStrategy<AsfStrategy>(node, Name("/"), parameters);
    }

    linkAB = topo.addLink("AB", 10_ms, {nodeA, nodeB});
    linkAD = topo.addLink("AD", 100_ms, {nodeA, nodeD});
    linkBC = topo.addLink("BC", 10_ms, {nodeB, nodeC});
    linkCD = topo.addLink("CD", 100_ms, {nodeC, nodeD});

    consumer = topo.addAppFace("c", nodeA);
    producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);

    topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, replyDelay);

    // Register producer prefix on consumer node
    topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 10);
    topo.registerPrefix(nodeA, linkAD->getFace(nodeA), PRODUCER_PREFIX, 5);
  }

  void
  runConsumer(size_t numInterests = 30)
  {
    topo.addIntervalConsumer(consumer->getClientFace(), PRODUCER_PREFIX, 1_s, numInterests);
    this->advanceClocks(10_ms, time::seconds(numInterests));
  }

protected:
  Name parameters;
  TopologyTester topo;

  TopologyNode nodeA;
  TopologyNode nodeB;
  TopologyNode nodeC;
  TopologyNode nodeD;

  shared_ptr<TopologyLink> linkAB;
  shared_ptr<TopologyLink> linkAD;
  shared_ptr<TopologyLink> linkBC;
  shared_ptr<TopologyLink> linkCD;

  shared_ptr<TopologyAppLink> consumer;
  shared_ptr<TopologyAppLink> producer;

  static const Name PRODUCER_PREFIX;
};

const Name AsfGridFixture::PRODUCER_PREFIX("/hr/C");

class AsfStrategyParametersGridFixture : public AsfGridFixture
{
protected:
  AsfStrategyParametersGridFixture()
    : AsfGridFixture(Name(AsfStrategy::getStrategyName())
                     .append("probing-interval~30000")
                     .append("max-timeouts~5"))
  {
  }
};

BOOST_FIXTURE_TEST_CASE(Basic, AsfGridFixture)
{
  // Both nodeB and nodeD have FIB entries to reach the producer
  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
  topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);

  runConsumer();

  // ASF should use the Face to nodeD because it has lower routing cost.
  // After 5 seconds, a probe Interest should be sent to the Face to nodeB,
  // and the probe should return Data quicker. ASF should then use the Face
  // to nodeB to forward the remaining Interests.
  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 30);
  // Because of exploration, will forward to AB and AD simultaneously at least once
  BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 25);
  BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 6);

  // If the link from nodeA to nodeB fails, ASF should start using the Face
  // to nodeD again.
  linkAB->fail();

  runConsumer();
  // We experience 3 timeouts and marked AB as timed out
  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 57);
  BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 36);
  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 24);

  // If the link from nodeA to nodeB recovers, ASF should probe the Face
  // to nodeB and start using it again.
  linkAB->recover();

  // Advance time to ensure probing is due
  this->advanceClocks(10_ms, 10_s);

  runConsumer();
  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 87);
  BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 50);
  BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 40);

  // If both links fail, nodeA should forward to the next hop with the lowest cost
  linkAB->fail();
  linkAD->fail();

  runConsumer();

  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 87);
  BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 65); // FIXME #3830
  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 57); // FIXME #3830
}

BOOST_FIXTURE_TEST_CASE(Nack, AsfGridFixture)
{
  // nodeB has a FIB entry to reach the producer, but nodeD does not
  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);

  // The strategy should first try to send to nodeD. But since nodeD does not have a route for
  // the producer's prefix, it should return a NO_ROUTE Nack. The strategy should then start using the Face to
  // nodeB.
  runConsumer();

  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nInNacks, 1);
  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 29);
  BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 29);

  // nodeD should receive 2 Interests: one for the very first Interest and
  // another from a probe
  BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
}

class AsfStrategyDelayedDataFixture : public AsfGridFixture
{
protected:
  AsfStrategyDelayedDataFixture()
    : AsfGridFixture(Name(AsfStrategy::getStrategyName()), 400_ms)
  {
  }
};

BOOST_FIXTURE_TEST_CASE(InterestForwarding, AsfStrategyDelayedDataFixture)
{
  Name name(PRODUCER_PREFIX);
  name.appendTimestamp();
  auto interest = makeInterest(name);

  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
  topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);

  // The first interest should go via link AD
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(10_ms, 100_ms);
  BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 1);

  // Second interest should go via link AB
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(10_ms, 100_ms);
  BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 1);

  // The third interest should again go via AD, since both the face from A is already used
  // and so asf should choose the earliest used face i.e. AD
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(10_ms, 100_ms);
  BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);

  this->advanceClocks(time::milliseconds(500), time::seconds(5));
  BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nInData, 1);
  BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 1);
  BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 1);
}

BOOST_AUTO_TEST_CASE(Retransmission) // Bug #4874
{
  // Avoid clearing pit entry for those incoming interest that have pit entry but no next hops
  /*
   *        +---------+   10ms   +---------+
   *        |  nodeB  | ------>  |  nodeC  |
   *        +---------+          +---------+
   */

  const Name PRODUCER_PREFIX = "/pnr/C";
  TopologyTester topo;

  TopologyNode nodeB = topo.addForwarder("B"),
               nodeC = topo.addForwarder("C");

  for (auto node : {nodeB, nodeC}) {
    topo.setStrategy<AsfStrategy>(node);
  }

  auto linkBC = topo.addLink("BC", time::milliseconds(10), {nodeB, nodeC});

  auto consumer = topo.addAppFace("c", nodeB),
       producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);

  topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, 100_ms);

  Name name(PRODUCER_PREFIX);
  name.appendTimestamp();
  auto interest = makeInterest(name);

  auto& pit = topo.getForwarder(nodeB).getPit();
  auto pitEntry = pit.insert(*interest).first;

  topo.getForwarder(nodeB).onOutgoingInterest(*interest, linkBC->getFace(nodeB), pitEntry);
  this->advanceClocks(time::milliseconds(100));

  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(time::milliseconds(100));

  auto outRecord = pitEntry->getOutRecord(linkBC->getFace(nodeB));
  BOOST_CHECK(outRecord != pitEntry->out_end());

  this->advanceClocks(time::milliseconds(100));
  BOOST_CHECK_EQUAL(linkBC->getFace(nodeC).getCounters().nOutData, 1);
  BOOST_CHECK_EQUAL(linkBC->getFace(nodeB).getCounters().nInData, 1);
}

BOOST_AUTO_TEST_CASE(PerUpstreamSuppression)
{
  /*
   *                          +---------+
   *                     +----|  nodeB  |----+
   *                     |    +---------+    |
   *                50ms |                   | 50ms
   *                     |                   |
   *                +---------+   50ms  +---------+
   *                |  nodeA  | <-----> |  nodeP  |
   *                +---------+         +---------+
   */

  const Name PRODUCER_PREFIX = "/suppress/me";
  TopologyTester topo;

  TopologyNode nodeA = topo.addForwarder("A"),
               nodeB = topo.addForwarder("B"),
               nodeP = topo.addForwarder("P");

  for (auto node : {nodeA, nodeB, nodeP}) {
    topo.setStrategy<AsfStrategy>(node);
  }

  auto linkAB = topo.addLink("AB", 50_ms, {nodeA, nodeB});
  auto linkAP = topo.addLink("AP", 50_ms, {nodeA, nodeP});
  auto linkBP = topo.addLink("BP", 50_ms, {nodeB, nodeP});

  auto consumer = topo.addAppFace("cons", nodeA),
       producer = topo.addAppFace("prod", nodeP, PRODUCER_PREFIX);

  topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX);

  topo.registerPrefix(nodeA, linkAP->getFace(nodeA), PRODUCER_PREFIX, 10);
  topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 1);
  topo.registerPrefix(nodeB, linkBP->getFace(nodeB), PRODUCER_PREFIX, 1);

  auto& faceA2B = linkAB->getFace(nodeA);
  auto& faceA2P = linkAP->getFace(nodeA);

  Name name(PRODUCER_PREFIX);
  name.appendTimestamp();
  // very short lifetime to make it expire within the initial retx suppression period (10ms)
  auto interest = makeInterest(name, false, 5_ms);

  // 1st interest should be sent to B
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 0);

  // 2nd interest should be sent to P and NOT suppressed
  interest->setInterestLifetime(100_ms);
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);

  this->advanceClocks(1_ms);

  // 3rd interest should be suppressed
  // without suppression, it would have been sent again to B as that's the earliest out-record
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);

  this->advanceClocks(2_ms); // 1st interest should expire now

  // 4th interest should be suppressed
  // without suppression, it would have been sent again to B because the out-record expired
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);

  this->advanceClocks(5_ms); // suppression window ends

  // 5th interest is sent to B and is outside the suppression window
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 2);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);

  this->advanceClocks(10_ms);

  // 6th interest is sent to P and is outside the suppression window
  interest->refreshNonce();
  consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
  this->advanceClocks(1_ms);
  BOOST_TEST(faceA2B.getCounters().nOutInterests == 2);
  BOOST_TEST(faceA2P.getCounters().nOutInterests == 2);
}

BOOST_AUTO_TEST_CASE(NoPitOutRecordAndProbeInterestNewNonce)
{
  /*                  +---------+
   *                  |  nodeD  |
   *                  +---------+
   *                       |
   *                       | 80ms
   *                       |
   *                       |
   *                  +---------+
   *           +----->|  nodeB  |<------+
   *           |      +---------+       |
   *      15ms |                        | 16ms
   *           v                        v
   *      +---------+              +---------+
   *      |  nodeA  |--------------|  nodeC  |
   *      +---------+     14ms      +---------+
   */

  const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
  TopologyTester topo;

  TopologyNode nodeA = topo.addForwarder("A"),
               nodeB = topo.addForwarder("B"),
               nodeC = topo.addForwarder("C"),
               nodeD = topo.addForwarder("D");

  for (auto node : {nodeA, nodeB, nodeC, nodeD}) {
    topo.setStrategy<AsfStrategy>(node);
  }

  auto linkAB = topo.addLink("AB", 15_ms, {nodeA, nodeB}),
       linkAC = topo.addLink("AC", 14_ms, {nodeA, nodeC}),
       linkBC = topo.addLink("BC", 16_ms, {nodeB, nodeC}),
       linkBD = topo.addLink("BD", 80_ms, {nodeB, nodeD});

  auto ping = topo.addAppFace("c", nodeA);
  auto pingServer = topo.addAppFace("p", nodeD, PRODUCER_PREFIX);
  topo.addEchoProducer(pingServer->getClientFace());

  topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 15);
  topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 14);
  topo.registerPrefix(nodeC, linkBC->getFace(nodeC), PRODUCER_PREFIX, 16);
  topo.registerPrefix(nodeB, linkBD->getFace(nodeB), PRODUCER_PREFIX, 80);

  // Send 6 interest since probes can be scheduled b/w 0-5 seconds
  for (int i = 1; i < 7; i++) {
    // Send ping number i
    Name name(PRODUCER_PREFIX);
    name.appendTimestamp();
    auto interest = makeInterest(name);
    ping->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
    auto nonce = interest->getNonce();

    // Don't know when the probe will be triggered since it is random between 0-5 seconds
    // or whether it will be triggered for this interest
    for (int j = 1; j <= 1000 && linkAB->getFace(nodeA).getCounters().nOutInterests != 1; ++j) {
      this->advanceClocks(1_ms);
    }

    // Check if probe is sent to B else send another ping
    if (linkAB->getFace(nodeA).getCounters().nOutInterests == 1) {
      // Get pitEntry of node A
      auto pitEntry = topo.getForwarder(nodeA).getPit().find(*interest);
      // Get outRecord associated with face towards B
      auto outRecord = pitEntry->getOutRecord(linkAB->getFace(nodeA));
      BOOST_REQUIRE(outRecord != pitEntry->out_end());

      // Check that Nonce of interest is not equal to Nonce of Probe
      BOOST_CHECK_NE(nonce, outRecord->getLastNonce());

      // B should not have received the probe interest yet
      BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 0);

      // i-1 interests through B when no probe
      BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i - 1);

      // After 15ms, B should get the probe interest
      this->advanceClocks(1_ms, 15_ms);
      BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 1);
      BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i);

      pitEntry = topo.getForwarder(nodeB).getPit().find(*interest);

      // Get outRecord associated with face towards D.
      outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));
      BOOST_CHECK(outRecord != pitEntry->out_end());

      // RTT between B and D
      this->advanceClocks(5_ms, 160_ms);
      outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));

      BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i);

      BOOST_CHECK(outRecord == pitEntry->out_end());

      // Data is returned for the ping after 15 ms - will result in false measurement
      // 14+16-15 = 15ms
      // Since outRecord == pitEntry->out_end()
      this->advanceClocks(1_ms, 15_ms);
      BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i+1);

      break;
    }
  }
}

BOOST_FIXTURE_TEST_CASE(IgnoreTimeouts, AsfStrategyParametersGridFixture)
{
  // Both nodeB and nodeD have FIB entries to reach the producer
  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
  topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);

  // Send 15 interests let it change to use the 10 ms link
  runConsumer(15);

  uint64_t outInterestsBeforeFailure = linkAD->getFace(nodeA).getCounters().nOutInterests;

  // Bring down 10 ms link
  linkAB->fail();

  // Send 5 interests, after the last one it will record the timeout
  // ready to switch for the next interest
  runConsumer(5);

  // Check that link has not been switched to 100 ms because max-timeouts = 5
  BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, outInterestsBeforeFailure);

  // Send 5 interests, check that 100 ms link is used
  runConsumer(5);

  BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, outInterestsBeforeFailure + 5);
}

BOOST_FIXTURE_TEST_CASE(ProbingInterval, AsfStrategyParametersGridFixture)
{
  // Both nodeB and nodeD have FIB entries to reach the producer
  topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
  topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);

  // Send 6 interests let it change to use the 10 ms link
  runConsumer(6);

  auto linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeD});
  topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 1);

  BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 0);

  // After 30 seconds a probe would be sent that would switch make ASF switch
  runConsumer(30);

  BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 1);
}

BOOST_AUTO_TEST_CASE(Parameters)
{
  FaceTable faceTable;
  Forwarder forwarder{faceTable};

  auto checkValidity = [&] (const std::string& parameters, bool isCorrect) {
    Name strategyName(Name(AsfStrategy::getStrategyName()).append(parameters));
    std::unique_ptr<AsfStrategy> strategy;
    BOOST_TEST_CONTEXT(parameters) {
      if (isCorrect) {
        strategy = make_unique<AsfStrategy>(forwarder, strategyName);
        BOOST_CHECK(strategy->m_retxSuppression != nullptr);
      }
      else {
        BOOST_CHECK_THROW(make_unique<AsfStrategy>(forwarder, strategyName), std::invalid_argument);
      }
    }
    return strategy;
  };

  auto strategy = checkValidity("", true);
  BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
  BOOST_TEST(strategy->m_nMaxTimeouts == 3);
  strategy = checkValidity("/probing-interval~30000/max-timeouts~5", true);
  BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
  BOOST_TEST(strategy->m_nMaxTimeouts == 5);
  strategy = checkValidity("/max-timeouts~5/probing-interval~30000", true);
  BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
  BOOST_TEST(strategy->m_nMaxTimeouts == 5);
  strategy = checkValidity("/probing-interval~1000", true);
  BOOST_TEST(strategy->m_probing.getProbingInterval() == 1_s);
  BOOST_TEST(strategy->m_nMaxTimeouts == 3);
  strategy = checkValidity("/max-timeouts~0", true);
  BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
  BOOST_TEST(strategy->m_nMaxTimeouts == 0);
  BOOST_TEST(strategy->m_retxSuppression->m_initialInterval == RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL);
  BOOST_TEST(strategy->m_retxSuppression->m_maxInterval == RetxSuppressionExponential::DEFAULT_MAX_INTERVAL);
  BOOST_TEST(strategy->m_retxSuppression->m_multiplier == RetxSuppressionExponential::DEFAULT_MULTIPLIER);

  checkValidity("/probing-interval~500", false); // minimum is 1 second
  checkValidity("/probing-interval~-5000", false);
  checkValidity("/max-timeouts~-1", false);
  checkValidity("/max-timeouts~ -1", false);
  checkValidity("/max-timeouts~1-0", false);
  checkValidity("/max-timeouts~1/probing-interval~-30000", false);
  checkValidity("/probing-interval~foo", false);
  checkValidity("/max-timeouts~1~2", false);
}

BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
BOOST_AUTO_TEST_SUITE_END() // Fw

} // namespace tests
} // namespace asf
} // namespace fw
} // namespace nfd
