fw: redesign best-route v2 strategy test case
New test case doesn't require exact timing, so that it's less likely
to fail on a busy/slow system.
refs #2126
Change-Id: I87fc34df40911de56e5acd2b5e5ff6f03c928ecf
diff --git a/tests/daemon/fw/best-route-strategy2.cpp b/tests/daemon/fw/best-route-strategy2.cpp
index e2104c8..fece22e 100644
--- a/tests/daemon/fw/best-route-strategy2.cpp
+++ b/tests/daemon/fw/best-route-strategy2.cpp
@@ -63,58 +63,64 @@
Pit& pit = forwarder.getPit();
shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
- const time::nanoseconds RETRANSMISSION60 = time::duration_cast<time::nanoseconds>(
- fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL * 0.6); // 60%
- const time::nanoseconds RETRANSMISSION120 = time::duration_cast<time::nanoseconds>(
- fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL * 1.2); // 120%
+ const time::nanoseconds RETRANSMISSION_10P = time::duration_cast<time::nanoseconds>(
+ fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL * 0.1); // 10%
+ const time::nanoseconds RETRANSMISSION_2 = time::duration_cast<time::nanoseconds>(
+ fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL * 2.0); // x2
+ // first Interest goes to nexthop with lowest FIB cost,
+ // however face1 is downstream so it cannot be used
pitEntry->insertOrUpdateInRecord(face1, *interest);
strategy.afterReceiveInterest(*face1, *interest, fibEntry, pitEntry);
BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 1);
BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.back().get<1>(), face2);
- // face1 is downstream so it cannot be used at this time
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION60);
- pitEntry->insertOrUpdateInRecord(face4, *interest);
- strategy.afterReceiveInterest(*face4, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 1);
- // ignored similar Interest
+ // downstream retransmits frequently, but the strategy should not send Interests
+ // more often than MIN_RETRANSMISSION_INTERVAL
+ scheduler::EventId retxFrom4Evt;
+ size_t nSentLast = strategy.m_sendInterestHistory.size();
+ time::steady_clock::TimePoint timeSentLast = time::steady_clock::now();
+ function<void()> periodicalRetxFrom4 = [&] {
+ pitEntry->insertOrUpdateInRecord(face4, *interest);
+ strategy.afterReceiveInterest(*face4, *interest, fibEntry, pitEntry);
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION60);
- pitEntry->insertOrUpdateInRecord(face4, *interest);
- strategy.afterReceiveInterest(*face4, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 2);
- BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.back().get<1>(), face1);
- // accepted retransmission, forward to an unused upstream
+ size_t nSent = strategy.m_sendInterestHistory.size();
+ if (nSent > nSentLast) {
+ BOOST_CHECK_EQUAL(nSent - nSentLast, 1);
+ time::steady_clock::TimePoint timeSent = time::steady_clock::now();
+ BOOST_CHECK_GE(timeSent - timeSentLast,
+ fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL);
+ nSentLast = nSent;
+ timeSentLast = timeSent;
+ }
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION120);
- pitEntry->insertOrUpdateInRecord(face5, *interest);
- strategy.afterReceiveInterest(*face5, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 3);
- BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.back().get<1>(), face3);
- // accepted similar Interest from new downstream, forward to an unused upstream
+ retxFrom4Evt = scheduler::schedule(RETRANSMISSION_10P, periodicalRetxFrom4);
+ };
+ periodicalRetxFrom4();
+ limitedIo.defer(fw::BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL * 16);
+ scheduler::cancel(retxFrom4Evt);
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION120);
- pitEntry->insertOrUpdateInRecord(face4, *interest);
- strategy.afterReceiveInterest(*face4, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 4);
- BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.back().get<1>(), face2);
- // accepted retransmission, forward to an eligible upstream with earliest OutRecord
-
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION60);
- pitEntry->insertOrUpdateInRecord(face5, *interest);
- strategy.afterReceiveInterest(*face5, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 4);
- // ignored retransmission
+ // nexthops for accepted retransmissions: follow FIB cost,
+ // later forward to an eligible upstream with earliest OutRecord
+ BOOST_REQUIRE_GE(strategy.m_sendInterestHistory.size(), 6);
+ BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[1].get<1>(), face1);
+ BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[2].get<1>(), face3);
+ BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[3].get<1>(), face2);
+ BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[4].get<1>(), face1);
+ BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory[5].get<1>(), face3);
fibEntry->removeNextHop(face1);
- limitedIo.run(LimitedIo::UNLIMITED_OPS, RETRANSMISSION60);
- pitEntry->insertOrUpdateInRecord(face5, *interest);
- strategy.afterReceiveInterest(*face5, *interest, fibEntry, pitEntry);
- BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 5);
- BOOST_CHECK_EQUAL(strategy.m_sendInterestHistory.back().get<1>(), face3);
- // accepted retransmission, forward to an eligible upstream with earliest OutRecord
+ strategy.m_sendInterestHistory.clear();
+ for (int i = 0; i < 3; ++i) {
+ limitedIo.defer(RETRANSMISSION_2);
+ pitEntry->insertOrUpdateInRecord(face5, *interest);
+ strategy.afterReceiveInterest(*face5, *interest, fibEntry, pitEntry);
+ }
+ BOOST_REQUIRE_EQUAL(strategy.m_sendInterestHistory.size(), 3);
+ BOOST_CHECK_NE(strategy.m_sendInterestHistory[0].get<1>(), face1);
+ BOOST_CHECK_NE(strategy.m_sendInterestHistory[1].get<1>(), face1);
+ BOOST_CHECK_NE(strategy.m_sendInterestHistory[2].get<1>(), face1);
// face1 cannot be used because it's gone from FIB entry
}