fw: Add ASF strategy parameters n-silent-timeouts & probing-interval
refs: #4193
Change-Id: I9572425a2fdcbf67b9886c2a5b6b50a10a0856e2
diff --git a/tests/daemon/fw/asf-strategy.t.cpp b/tests/daemon/fw/asf-strategy.t.cpp
index 750effd..5759e68 100644
--- a/tests/daemon/fw/asf-strategy.t.cpp
+++ b/tests/daemon/fw/asf-strategy.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -46,7 +46,8 @@
class AsfGridFixture : public UnitTestTimeFixture
{
protected:
- AsfGridFixture()
+ AsfGridFixture(Name parameters = AsfStrategy::getStrategyName())
+ : parameters(parameters)
{
/*
* +---------+
@@ -69,10 +70,10 @@
nodeC = topo.addForwarder("C");
nodeD = topo.addForwarder("D");
- topo.setStrategy<fw::AsfStrategy>(nodeA);
- topo.setStrategy<fw::AsfStrategy>(nodeB);
- topo.setStrategy<fw::AsfStrategy>(nodeC);
- topo.setStrategy<fw::AsfStrategy>(nodeD);
+ topo.setStrategy<AsfStrategy>(nodeA, Name("ndn:/"), parameters);
+ topo.setStrategy<AsfStrategy>(nodeB, Name("ndn:/"), parameters);
+ topo.setStrategy<AsfStrategy>(nodeC, Name("ndn:/"), parameters);
+ topo.setStrategy<AsfStrategy>(nodeD, Name("ndn:/"), parameters);
linkAB = topo.addLink("AB", time::milliseconds(10), {nodeA, nodeB});
linkAD = topo.addLink("AD", time::milliseconds(100), {nodeA, nodeD});
@@ -89,13 +90,14 @@
}
void
- runConsumer()
+ runConsumer(int numInterests = 30)
{
- topo.addIntervalConsumer(consumer->getClientFace(), PRODUCER_PREFIX, time::seconds(1), 30);
- this->advanceClocks(time::milliseconds(10), time::seconds(30));
+ topo.addIntervalConsumer(consumer->getClientFace(), PRODUCER_PREFIX, time::seconds(1), numInterests);
+ this->advanceClocks(time::milliseconds(10), time::seconds(numInterests));
}
protected:
+ Name parameters;
TopologyTester topo;
TopologyNode nodeA;
@@ -114,6 +116,17 @@
static const Name PRODUCER_PREFIX;
};
+class AsfStrategyParametersGridFixture : public AsfGridFixture
+{
+protected:
+ AsfStrategyParametersGridFixture()
+ : AsfGridFixture(Name(AsfStrategy::getStrategyName())
+ .append("probing-interval~30000")
+ .append("n-silent-timeouts~5"))
+ {
+ }
+};
+
const Name AsfGridFixture::PRODUCER_PREFIX = Name("ndn:/hr/C");
BOOST_FIXTURE_TEST_CASE(Basic, AsfGridFixture)
@@ -214,7 +227,7 @@
nodeD = topo.addForwarder("D");
for (TopologyNode node : {nodeA, nodeB, nodeC, nodeD}) {
- topo.setStrategy<fw::AsfStrategy>(node);
+ topo.setStrategy<AsfStrategy>(node);
}
shared_ptr<TopologyLink> linkAB = topo.addLink("AB", time::milliseconds(15), {nodeA, nodeB}),
@@ -304,6 +317,91 @@
}
}
+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);
+
+ int outInterestsBeforeFailure = linkAD->getFace(nodeA).getCounters().nOutInterests;
+
+ // Bring down 10 ms link
+ linkAB->fail();
+
+ // Send 6 interests, first 5 will be ignored and on the 6th it will record the timeout
+ // ready to switch for the next interest
+ runConsumer(6);
+
+ // Check that link has not been switched to 100 ms because n-silent-timeouts = 5
+ BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests - outInterestsBeforeFailure, 0);
+
+ // 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);
+
+ shared_ptr<TopologyLink> linkAC = topo.addLink("AC", time::milliseconds(5), {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);
+}
+
+class ParametersFixture
+{
+public:
+ void
+ checkValidity(std::string parameters, bool isCorrect)
+ {
+ Name strategyName(Name(AsfStrategy::getStrategyName()).append(parameters));
+ if (isCorrect) {
+ BOOST_CHECK_NO_THROW(make_unique<AsfStrategy>(forwarder, strategyName));
+ }
+ else {
+ BOOST_CHECK_THROW(make_unique<AsfStrategy>(forwarder, strategyName), std::invalid_argument);
+ }
+ }
+
+protected:
+ Forwarder forwarder;
+};
+
+BOOST_FIXTURE_TEST_CASE(InstantiationTest, ParametersFixture)
+{
+ checkValidity("/probing-interval~30000/n-silent-timeouts~5", true);
+ checkValidity("/n-silent-timeouts~5/probing-interval~30000", true);
+ checkValidity("/probing-interval~30000", true);
+ checkValidity("/n-silent-timeouts~5", true);
+ checkValidity("", true);
+
+ checkValidity("/probing-interval~500", false); // At least 1 seconds
+ checkValidity("/probing-interval~-5000", false);
+ checkValidity("/n-silent-timeouts~-5", false);
+ checkValidity("/n-silent-timeouts~-5/probing-interval~-30000", false);
+ checkValidity("/n-silent-timeouts", false);
+ checkValidity("/probing-interval~", false);
+ checkValidity("/~1000", false);
+ checkValidity("/probing-interval~foo", false);
+ checkValidity("/n-silent-timeouts~1~2", false);
+}
+
BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
BOOST_AUTO_TEST_SUITE_END() // Fw
diff --git a/tests/daemon/fw/strategy-instantiation.t.cpp b/tests/daemon/fw/strategy-instantiation.t.cpp
index 391c761..cde39bb 100644
--- a/tests/daemon/fw/strategy-instantiation.t.cpp
+++ b/tests/daemon/fw/strategy-instantiation.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -75,7 +75,7 @@
using Tests = boost::mpl::vector<
Test<AccessStrategy, false, 1>,
- Test<AsfStrategy, true, 2>,
+ Test<AsfStrategy, true, 3>,
Test<BestRouteStrategy, false, 1>,
Test<BestRouteStrategy2, false, 5>,
Test<ClientControlStrategy, false, 2>,
diff --git a/tests/daemon/fw/topology-tester.hpp b/tests/daemon/fw/topology-tester.hpp
index 892dc01..cbd8fd9 100644
--- a/tests/daemon/fw/topology-tester.hpp
+++ b/tests/daemon/fw/topology-tester.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -209,10 +209,11 @@
*/
template<typename S>
void
- setStrategy(TopologyNode i, Name prefix = Name("ndn:/"))
+ setStrategy(TopologyNode i, Name prefix = Name("ndn:/"),
+ Name instanceName = S::getStrategyName())
{
Forwarder& forwarder = this->getForwarder(i);
- choose<S>(forwarder, prefix);
+ choose<S>(forwarder, prefix, instanceName);
}
/** \brief makes a link that interconnects two or more forwarders