blob: a69c3a55563097038a816d775af1599576fe4d00 [file] [log] [blame]
Junxiao Shi67ba8d22015-08-21 21:21:28 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87fc0f82018-04-11 23:43:51 -04002/*
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shi67ba8d22015-08-21 21:21:28 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "fw/multicast-strategy.hpp"
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040027#include "common/global.hpp"
Junxiao Shi67ba8d22015-08-21 21:21:28 -070028
29#include "tests/test-common.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/daemon/face/dummy-face.hpp"
Alexander Afanasyev40604e32021-02-17 12:06:26 -050031#include "choose-strategy.hpp"
Davide Pesavento3dade002019-03-19 11:29:56 -060032#include "strategy-tester.hpp"
Ashlesh Gawandec1d48372020-08-02 22:30:11 -070033#include "topology-tester.hpp"
Junxiao Shi67ba8d22015-08-21 21:21:28 -070034
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040035namespace nfd::tests {
Junxiao Shi67ba8d22015-08-21 21:21:28 -070036
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040037using MulticastStrategyTester = StrategyTester<fw::MulticastStrategy>;
Junxiao Shi890afe92016-12-15 14:34:34 +000038NFD_REGISTER_STRATEGY(MulticastStrategyTester);
39
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040040class MulticastStrategyFixture : public GlobalIoTimeFixture
Junxiao Shi890afe92016-12-15 14:34:34 +000041{
42protected:
43 MulticastStrategyFixture()
Alexander Afanasyev40604e32021-02-17 12:06:26 -050044 : strategy(choose<MulticastStrategyTester>(forwarder))
45 , face1(make_shared<DummyFace>())
Junxiao Shi890afe92016-12-15 14:34:34 +000046 , face2(make_shared<DummyFace>())
47 , face3(make_shared<DummyFace>())
48 {
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040049 faceTable.add(face1);
50 faceTable.add(face2);
51 faceTable.add(face3);
Junxiao Shi890afe92016-12-15 14:34:34 +000052 }
53
Davide Pesavento03a75f62021-03-09 20:38:38 -050054 bool
55 didSendInterestTo(const Face& face) const
56 {
57 auto it = std::find_if(strategy.sendInterestHistory.begin(),
58 strategy.sendInterestHistory.end(),
59 [&] (const auto& elem) { return elem.outFaceId == face.getId(); });
60 return it != strategy.sendInterestHistory.end();
61 }
62
Junxiao Shi890afe92016-12-15 14:34:34 +000063protected:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040064 FaceTable faceTable;
65 Forwarder forwarder{faceTable};
Alexander Afanasyev40604e32021-02-17 12:06:26 -050066 MulticastStrategyTester& strategy;
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040067 Fib& fib{forwarder.getFib()};
68 Pit& pit{forwarder.getPit()};
69
Junxiao Shi890afe92016-12-15 14:34:34 +000070 shared_ptr<DummyFace> face1;
71 shared_ptr<DummyFace> face2;
72 shared_ptr<DummyFace> face3;
73};
74
Junxiao Shi5e5e4452015-09-24 16:56:52 -070075BOOST_AUTO_TEST_SUITE(Fw)
Junxiao Shi890afe92016-12-15 14:34:34 +000076BOOST_FIXTURE_TEST_SUITE(TestMulticastStrategy, MulticastStrategyFixture)
Junxiao Shi67ba8d22015-08-21 21:21:28 -070077
Ashlesh Gawandec1d48372020-08-02 22:30:11 -070078BOOST_AUTO_TEST_CASE(Bug5123)
79{
80 fib::Entry& fibEntry = *fib.insert(Name()).first;
81 fib.addOrUpdateNextHop(fibEntry, *face2, 0);
82
83 // Send an Interest from face 1 to face 2
Davide Pesavento03a75f62021-03-09 20:38:38 -050084 auto interest = makeInterest("ndn:/H0D6i5fc");
85 auto pitEntry = pit.insert(*interest).first;
Ashlesh Gawandec1d48372020-08-02 22:30:11 -070086 pitEntry->insertOrUpdateInRecord(*face1, *interest);
87
Teng Liangd94b7b32022-07-10 21:29:37 +080088 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face1), pitEntry);
Ashlesh Gawandec1d48372020-08-02 22:30:11 -070089 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
Davide Pesavento03a75f62021-03-09 20:38:38 -050090 BOOST_CHECK_EQUAL(strategy.sendInterestHistory.size(), 1);
Ashlesh Gawandec1d48372020-08-02 22:30:11 -070091
92 // Advance more than default suppression
93 this->advanceClocks(15_ms);
94
95 // Get same interest from face 2 which does not have anywhere to go
96 pitEntry = pit.insert(*interest).first;
97 pitEntry->insertOrUpdateInRecord(*face2, *interest);
98
Teng Liangd94b7b32022-07-10 21:29:37 +080099 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face2), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500100 // Since the interest is the same as the one sent out earlier, the PIT entry should not be
101 // rejected, as any data coming back must be able to satisfy the original interest from face 1
Ashlesh Gawandec1d48372020-08-02 22:30:11 -0700102 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
103
104 /*
105 * +---------+ +---------+ +---------+
106 * | nodeA |------------| nodeB |----------| nodeC |
107 * +---------+ 10ms +---------+ 100ms +---------+
108 */
109
110 const Name PRODUCER_PREFIX = "/ndn/edu/nodeC/ping";
111
112 TopologyTester topo;
113 TopologyNode nodeA = topo.addForwarder("A"),
114 nodeB = topo.addForwarder("B"),
115 nodeC = topo.addForwarder("C");
116
117 for (TopologyNode node : {nodeA, nodeB, nodeC}) {
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400118 topo.setStrategy<fw::MulticastStrategy>(node);
Ashlesh Gawandec1d48372020-08-02 22:30:11 -0700119 }
120
121 shared_ptr<TopologyLink> linkAB = topo.addLink("AB", 10_ms, {nodeA, nodeB}),
122 linkBC = topo.addLink("BC", 100_ms, {nodeB, nodeC});
123
124 shared_ptr<TopologyAppLink> appA = topo.addAppFace("cA", nodeA),
125 appB = topo.addAppFace("cB", nodeB),
126 pingServer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
127 topo.addEchoProducer(pingServer->getClientFace());
128 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 10);
129 topo.registerPrefix(nodeB, linkAB->getFace(nodeB), PRODUCER_PREFIX, 10);
130 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX, 100);
131
132 Name name(PRODUCER_PREFIX);
133 name.appendTimestamp();
134 interest = makeInterest(name);
135 appA->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
136
137 this->advanceClocks(10_ms, 20_ms);
138
139 // AppB expresses the same interest
140 interest->refreshNonce();
141 appB->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
142 this->advanceClocks(10_ms, 200_ms);
143
144 // Data should have made to appB
145 BOOST_CHECK_EQUAL(linkBC->getFace(nodeB).getCounters().nInData, 1);
146 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 0);
147
148 this->advanceClocks(10_ms, 10_ms);
149 // nodeA should have gotten the data successfully
150 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 1);
151 BOOST_CHECK_EQUAL(topo.getForwarder(nodeA).getCounters().nUnsolicitedData, 0);
152}
153
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700154BOOST_AUTO_TEST_CASE(Forward2)
155{
Junxiao Shia6de4292016-07-12 02:08:10 +0000156 fib::Entry& fibEntry = *fib.insert(Name()).first;
Ju Pand8315bf2019-07-31 06:59:07 +0000157 fib.addOrUpdateNextHop(fibEntry, *face1, 0);
158 fib.addOrUpdateNextHop(fibEntry, *face2, 0);
159 fib.addOrUpdateNextHop(fibEntry, *face3, 0);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700160
Davide Pesavento03a75f62021-03-09 20:38:38 -0500161 auto interest = makeInterest("ndn:/H0D6i5fc");
162 auto pitEntry = pit.insert(*interest).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000163 pitEntry->insertOrUpdateInRecord(*face3, *interest);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700164
Teng Liangd94b7b32022-07-10 21:29:37 +0800165 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face3), pitEntry);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700166 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
167 BOOST_CHECK_EQUAL(strategy.sendInterestHistory.size(), 2);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500168 BOOST_TEST(didSendInterestTo(*face1));
169 BOOST_TEST(didSendInterestTo(*face2));
Ashlesh Gawandee38e2612017-02-25 07:23:41 +0000170
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400171 const auto TICK = time::duration_cast<time::nanoseconds>(
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400172 fw::RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL) / 10;
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700173
Ashlesh Gawandeecdbe5f2017-03-04 03:08:24 +0000174 // downstream retransmits frequently, but the strategy should not send Interests
175 // more often than DEFAULT_MIN_RETX_INTERVAL
176 scheduler::EventId retxFrom4Evt;
177 size_t nSentLast = strategy.sendInterestHistory.size();
Davide Pesavento412c9822021-07-02 00:21:05 -0400178 auto timeSentLast = time::steady_clock::now();
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400179 std::function<void()> periodicalRetxFrom4; // let periodicalRetxFrom4 lambda capture itself
Ashlesh Gawandeecdbe5f2017-03-04 03:08:24 +0000180 periodicalRetxFrom4 = [&] {
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000181 pitEntry->insertOrUpdateInRecord(*face3, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800182 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face3), pitEntry);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700183
Ashlesh Gawandeecdbe5f2017-03-04 03:08:24 +0000184 size_t nSent = strategy.sendInterestHistory.size();
185 if (nSent > nSentLast) {
186 // Multicast strategy should multicast the interest to other two faces
187 BOOST_CHECK_EQUAL(nSent - nSentLast, 2);
Davide Pesavento3dade002019-03-19 11:29:56 -0600188 auto timeSent = time::steady_clock::now();
Ashlesh Gawandeecdbe5f2017-03-04 03:08:24 +0000189 BOOST_CHECK_GE(timeSent - timeSentLast, TICK * 8);
190 nSentLast = nSent;
191 timeSentLast = timeSent;
192 }
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700193
Davide Pesavento3dade002019-03-19 11:29:56 -0600194 retxFrom4Evt = getScheduler().schedule(TICK * 5, periodicalRetxFrom4);
Ashlesh Gawandeecdbe5f2017-03-04 03:08:24 +0000195 };
196 periodicalRetxFrom4();
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400197 this->advanceClocks(TICK, fw::RetxSuppressionExponential::DEFAULT_MAX_INTERVAL * 16);
Davide Pesavento3dade002019-03-19 11:29:56 -0600198 retxFrom4Evt.cancel();
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700199}
200
Alexander Afanasyev4400e422021-02-17 11:17:33 -0500201BOOST_AUTO_TEST_CASE(LoopingInterest)
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700202{
Junxiao Shia6de4292016-07-12 02:08:10 +0000203 fib::Entry& fibEntry = *fib.insert(Name()).first;
Ju Pand8315bf2019-07-31 06:59:07 +0000204 fib.addOrUpdateNextHop(fibEntry, *face1, 0);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700205
Davide Pesavento03a75f62021-03-09 20:38:38 -0500206 auto interest = makeInterest("ndn:/H0D6i5fc");
207 auto pitEntry = pit.insert(*interest).first;
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000208 pitEntry->insertOrUpdateInRecord(*face1, *interest);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700209
Teng Liangd94b7b32022-07-10 21:29:37 +0800210 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face1), pitEntry);
Alexander Afanasyev4400e422021-02-17 11:17:33 -0500211 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700212 BOOST_CHECK_EQUAL(strategy.sendInterestHistory.size(), 0);
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700213}
214
Davide Pesavento03a75f62021-03-09 20:38:38 -0500215BOOST_AUTO_TEST_CASE(RetxSuppression)
216{
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400217 const auto suppressPeriod = fw::RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL;
Davide Pesavento03a75f62021-03-09 20:38:38 -0500218 BOOST_ASSERT(suppressPeriod >= 8_ms);
219
220 // Set up the FIB
221 fib::Entry& fibEntry = *fib.insert(Name()).first;
222 fib.addOrUpdateNextHop(fibEntry, *face1, 0);
223 fib.addOrUpdateNextHop(fibEntry, *face2, 0);
224 fib.addOrUpdateNextHop(fibEntry, *face3, 0);
225
226 // Interest arrives from face 1
227 auto interest = makeInterest("/t8ZiSOi3");
228 auto pitEntry = pit.insert(*interest).first;
229 pitEntry->insertOrUpdateInRecord(*face1, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800230 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face1), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500231
232 // forwarded to faces 2 and 3
233 BOOST_TEST(strategy.sendInterestHistory.size() == 2);
234 BOOST_TEST(didSendInterestTo(*face2));
235 BOOST_TEST(didSendInterestTo(*face3));
236 strategy.sendInterestHistory.clear();
237
238 // still within the initial suppression period for face 2 and 3
239 this->advanceClocks(suppressPeriod - 5_ms);
240
241 // Interest arrives from face 2
242 interest->refreshNonce();
243 pitEntry = pit.insert(*interest).first;
244 pitEntry->insertOrUpdateInRecord(*face2, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800245 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face2), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500246
247 // forwarded only to face 1, suppressed on face 3
248 BOOST_TEST(strategy.sendInterestHistory.size() == 1);
249 BOOST_TEST(didSendInterestTo(*face1));
250 strategy.sendInterestHistory.clear();
251
252 // faces 2 and 3 no longer inside the suppression window
253 this->advanceClocks(7_ms);
254
255 // Interest arrives from face 3
256 interest->refreshNonce();
257 pitEntry = pit.insert(*interest).first;
258 pitEntry->insertOrUpdateInRecord(*face3, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800259 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face3), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500260
261 // suppressed on face 1, forwarded on face 2 (and suppression window doubles)
262 BOOST_TEST(strategy.sendInterestHistory.size() == 1);
263 BOOST_TEST(didSendInterestTo(*face2));
264 strategy.sendInterestHistory.clear();
265
266 // face 1 exits the suppression period, face 2 still inside
267 this->advanceClocks(2 * suppressPeriod - 2_ms);
268
269 // Interest arrives from face 3
270 interest->refreshNonce();
271 pitEntry = pit.insert(*interest).first;
272 pitEntry->insertOrUpdateInRecord(*face3, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800273 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face3), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500274
275 // forwarded only to face 1, suppressed on face 2
276 BOOST_TEST(strategy.sendInterestHistory.size() == 1);
277 BOOST_TEST(didSendInterestTo(*face1));
278 strategy.sendInterestHistory.clear();
279
280 // face 2 exits the suppression period
281 this->advanceClocks(3_ms);
282
283 // Interest arrives from face 1
284 interest->refreshNonce();
285 pitEntry = pit.insert(*interest).first;
286 pitEntry->insertOrUpdateInRecord(*face1, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800287 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face1), pitEntry);
Davide Pesavento03a75f62021-03-09 20:38:38 -0500288
289 // forwarded to faces 2 and 3
290 BOOST_TEST(strategy.sendInterestHistory.size() == 2);
291 BOOST_TEST(didSendInterestTo(*face2));
292 BOOST_TEST(didSendInterestTo(*face3));
293 strategy.sendInterestHistory.clear();
294}
295
296BOOST_AUTO_TEST_CASE(NewNextHop)
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500297{
298 fib::Entry& fibEntry = *fib.insert(Name()).first;
299 fib.addOrUpdateNextHop(fibEntry, *face1, 0);
300 fib.addOrUpdateNextHop(fibEntry, *face2, 0);
301
Davide Pesavento03a75f62021-03-09 20:38:38 -0500302 auto interest = makeInterest("ndn:/H0D6i5fc");
303 auto pitEntry = pit.insert(*interest).first;
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500304 pitEntry->insertOrUpdateInRecord(*face1, *interest);
305
Teng Liangd94b7b32022-07-10 21:29:37 +0800306 strategy.afterReceiveInterest(*interest, FaceEndpoint(*face1), pitEntry);
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500307 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
308 BOOST_CHECK_EQUAL(strategy.sendInterestHistory.size(), 1);
309
310 fib.addOrUpdateNextHop(fibEntry, *face3, 0);
311 BOOST_CHECK_EQUAL(strategy.rejectPendingInterestHistory.size(), 0);
312 BOOST_CHECK_EQUAL(strategy.sendInterestHistory.size(), 2);
313}
314
315BOOST_AUTO_TEST_SUITE(LocalhopScope)
316
317class ForwardAsyncFixture : public MulticastStrategyFixture
318{
319protected:
320 shared_ptr<Face> inFace1;
321 shared_ptr<Face> inFace2;
322 shared_ptr<Face> fibFace1;
323 shared_ptr<Face> fibFace2;
324 shared_ptr<Face> newFibFace;
325
326 size_t expectedInterests = 0;
327};
328
329class BasicNonLocal : public ForwardAsyncFixture
330{
331protected:
332 BasicNonLocal()
333 {
334 inFace1 = face1;
335 // inFace2 = nullptr;
336 fibFace1 = face1;
337 fibFace2 = face2;
338 newFibFace = face3;
339 expectedInterests = 0; // anything received on non-local face can only be sent to local face
340 }
341};
342
343class NewFibLocal : public ForwardAsyncFixture
344{
345protected:
346 NewFibLocal()
347 {
348 inFace1 = face1;
349 // inFace2 = nullptr;
350 fibFace1 = face1;
351 fibFace2 = face2;
352 newFibFace = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
353 expectedInterests = 1;
354
355 faceTable.add(newFibFace);
356 }
357};
358
359class InFaceLocal : public ForwardAsyncFixture
360{
361protected:
362 InFaceLocal()
363 {
364 inFace1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
365 // inFace2 = nullptr;
366 fibFace1 = face1;
367 fibFace2 = face2;
368 newFibFace = face3;
369 expectedInterests = 1;
370
371 faceTable.add(inFace1);
372 }
373};
374
375class InFaceLocalSameNewFace : public ForwardAsyncFixture
376{
377protected:
378 InFaceLocalSameNewFace()
379 {
380 inFace1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
381 // inFace2 = nullptr;
382 fibFace1 = face1;
383 fibFace2 = face2;
384 newFibFace = inFace1;
385 expectedInterests = 0;
386
387 faceTable.add(inFace1);
388 }
389};
390
391class InFaceLocalAdHocSameNewFace : public ForwardAsyncFixture
392{
393protected:
394 InFaceLocalAdHocSameNewFace()
395 {
396 inFace1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL,
397 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
398 ndn::nfd::LINK_TYPE_AD_HOC);
399 // inFace2 = nullptr;
400 fibFace1 = face1;
401 fibFace2 = face2;
402 newFibFace = inFace1;
403 expectedInterests = 1;
404
405 faceTable.add(inFace1);
406 }
407};
408
409class InFaceLocalAndNonLocal1 : public ForwardAsyncFixture
410{
411protected:
412 InFaceLocalAndNonLocal1()
413 {
414 inFace1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
415 inFace2 = face1;
416 fibFace1 = face1;
417 fibFace2 = face2;
418 newFibFace = face3;
419 expectedInterests = 1;
420
421 faceTable.add(inFace1);
422 }
423};
424
425class InFaceLocalAndNonLocal2 : public ForwardAsyncFixture
426{
427protected:
428 InFaceLocalAndNonLocal2()
429 {
430 inFace1 = face1;
431 inFace2 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
432 fibFace1 = face1;
433 fibFace2 = face2;
434 newFibFace = face3;
435 expectedInterests = 1;
436
437 faceTable.add(inFace2);
438 }
439};
440
441class InFaceSelection1 : public ForwardAsyncFixture
442{
443protected:
444 InFaceSelection1()
445 {
446 inFace1 = face1;
447 // inFace2 = nullptr;
448 fibFace1 = face3;
449 fibFace2 = face2;
450 newFibFace = face1;
451
452 expectedInterests = 0;
453 }
454};
455
456class InFaceSelection2 : public ForwardAsyncFixture
457{
458protected:
459 InFaceSelection2()
460 {
461 inFace1 = face2;
462 inFace2 = face1;
463 fibFace1 = face2;
464 fibFace2 = face3;
465 newFibFace = face1;
466
467 // this test will trigger the check for additional branch, but it
468 // still is not going to pass the localhop check
469 expectedInterests = 0;
470 }
471};
472
473using Tests = boost::mpl::vector<
474 BasicNonLocal,
475 NewFibLocal,
476 InFaceLocal,
477 InFaceLocalSameNewFace,
478 InFaceLocalAdHocSameNewFace,
479 InFaceLocalAndNonLocal1,
480 InFaceLocalAndNonLocal2,
481 InFaceSelection1,
482 InFaceSelection2
483>;
484
485BOOST_FIXTURE_TEST_CASE_TEMPLATE(ForwardAsync, T, Tests, T)
486{
487 fib::Entry& fibEntry = *this->fib.insert(Name("/localhop")).first;
488 this->fib.addOrUpdateNextHop(fibEntry, *this->fibFace1, 0);
489 this->fib.addOrUpdateNextHop(fibEntry, *this->fibFace2, 0);
490
Davide Pesavento03a75f62021-03-09 20:38:38 -0500491 auto interest = makeInterest("ndn:/localhop/H0D6i5fc");
492 auto pitEntry = this->pit.insert(*interest).first;
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500493 pitEntry->insertOrUpdateInRecord(*this->inFace1, *interest);
Teng Liangd94b7b32022-07-10 21:29:37 +0800494 this->strategy.afterReceiveInterest(*interest, FaceEndpoint(*this->inFace1), pitEntry);
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500495
496 if (this->inFace2 != nullptr) {
Davide Pesavento03a75f62021-03-09 20:38:38 -0500497 auto interest2 = makeInterest("ndn:/localhop/H0D6i5fc");
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500498 pitEntry->insertOrUpdateInRecord(*this->inFace2, *interest2);
Teng Liangd94b7b32022-07-10 21:29:37 +0800499 this->strategy.afterReceiveInterest(*interest2, FaceEndpoint(*this->inFace2), pitEntry);
Alexander Afanasyev40604e32021-02-17 12:06:26 -0500500 }
501
502 this->strategy.sendInterestHistory.clear();
503 this->fib.addOrUpdateNextHop(fibEntry, *this->newFibFace, 0);
504 BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), this->expectedInterests);
505}
506
507BOOST_AUTO_TEST_SUITE_END() // LocalhopScope
Junxiao Shi5e5e4452015-09-24 16:56:52 -0700508BOOST_AUTO_TEST_SUITE_END() // TestMulticastStrategy
509BOOST_AUTO_TEST_SUITE_END() // Fw
Junxiao Shi67ba8d22015-08-21 21:21:28 -0700510
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400511} // namespace nfd::tests