Bug #2403
Updated by Junxiao Shi almost 10 years ago
Test case to reproduce: ``` BOOST_FIXTURE_TEST_CASE(Overhead, TwoLaptopsFixture) { /* * /------------------\ /------------------\ * | intervalConsumer | | intervalConsumer | * \------------------/ A \------------------/ * ^ v f ^ v * | v /laptops/M t | v /laptops/M * | e | * v r v * /laptops << +--------+ >> /laptops /laptops << +--------+ >> /laptops * +----->| router |<------+ 1 +----->| router |<------+ * | +--------+ | | +--------+ | * 10ms | | 20ms === s ==> 10ms | | 20ms * v v e v v * +---------+ +---------+ c +---------+ +---------+ * | laptopA | | laptopB | o | laptopA | | laptopB | * +---------+ +---------+ n +---------+ +---------+ * ^ v d * | v /laptops/M * v * /--------------\ * | echoProducer | * \--------------/ */ // laptopA has prefix in router FIB; laptopB is unused in this test case topo.registerPrefix(router, linkA->getFace(router), "ndn:/laptops"); topo.registerPrefix(router, linkB->getFace(router), "ndn:/laptops"); shared_ptr<TopologyAppLink> producerA = topo.addAppFace(laptopA, "ndn:/laptops/A"); topo.addEchoProducer(*producerA->getClientFace()); // to build up "correct" RTO value shared_ptr<TopologyAppLink> consumer = topo.addAppFace(router); topo.addIntervalConsumer(*consumer->getClientFace(), "ndn:/laptops/A", time::milliseconds(10), 100); this->advanceClocks(time::milliseconds(1), time::seconds(1)); auto me = topo.getForwarder(router).getMeasurements().findLongestPrefixMatch("ndn:/laptops/A"); BOOST_REQUIRE(me != nullptr); auto mi = me->getStrategyInfo<fw::AccessStrategy::MtInfo>(); BOOST_REQUIRE(mi != nullptr); auto rto = mi->rtt.computeRto(); BOOST_CHECK(time::milliseconds(10) < rto && rto < time::milliseconds(30)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 100); BOOST_CHECK_EQUAL(linkA->getFace(laptopA)->m_sentDatas.size(), 100); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 3); linkA->getFace(router)->m_sentInterests.clear(); linkA->getFace(laptopA)->m_sentDatas.clear(); linkB->getFace(router)->m_sentInterests.clear(); // actual test producerA->fail(); topo.addIntervalConsumer(*consumer->getClientFace(), "ndn:/laptops/A", time::milliseconds(31), 10); // unicast to laptopA this->advanceClocks(time::milliseconds(1), time::milliseconds(10)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 1); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 0); // multicast this->advanceClocks(time::milliseconds(1), time::milliseconds(20)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 1); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 1); // unicast to laptopA this->advanceClocks(time::milliseconds(1), time::milliseconds(10)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 2); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 1); // multicast this->advanceClocks(time::milliseconds(1), time::milliseconds(20)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 2); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 2); // unicast to laptopA this->advanceClocks(time::milliseconds(1), time::milliseconds(10)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 3); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 2); // multicast this->advanceClocks(time::milliseconds(1), time::milliseconds(20)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 3); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 3); this->advanceClocks(time::milliseconds(5), time::seconds(1)); BOOST_CHECK_EQUAL(linkA->getFace(router)->m_sentInterests.size(), 10); BOOST_CHECK_EQUAL(linkB->getFace(router)->m_sentInterests.size(), 10); this->advanceClocks(time::milliseconds(5), time::seconds(5)); // all consumers should be done more than 4 seconds ago me = topo.getForwarder(router).getMeasurements().findLongestPrefixMatch("ndn:/laptops/A"); BOOST_CHECK(me == nullptr); } ``` Actual: (as shown in test assertions) after producer failure, Interests are unicasted to where the producer was, and then multicasted after an RTO. This continues until MeasurementsEntry expires. RTO Expected: after producer failure, Interests are multicasted right away. away