blob: 17a19a7d6a74d7a0640192c811cf45ce28e93ac3 [file] [log] [blame]
Vince Lehman8a4c29e2016-07-11 08:49:35 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -05002/*
awlane5fdcbec2023-12-15 14:56:05 -06003 * Copyright (c) 2014-2024, Regents of the University of California,
Vince Lehman8a4c29e2016-07-11 08:49:35 +00004 * 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/asf-strategy.hpp"
27
awlane5fdcbec2023-12-15 14:56:05 -060028#include "tests/daemon/face/dummy-face.hpp"
29
Junxiao Shi890afe92016-12-15 14:34:34 +000030#include "strategy-tester.hpp"
Vince Lehman8a4c29e2016-07-11 08:49:35 +000031#include "topology-tester.hpp"
32
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040033namespace nfd::tests {
Vince Lehman8a4c29e2016-07-11 08:49:35 +000034
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040035using fw::AsfStrategy;
awlane5fdcbec2023-12-15 14:56:05 -060036using fw::asf::FaceInfo;
Vince Lehman8a4c29e2016-07-11 08:49:35 +000037
Junxiao Shi890afe92016-12-15 14:34:34 +000038// The tester is unused in this file, but it's used in various templated test suites.
Davide Pesavento14e71f02019-03-28 17:35:25 -040039using AsfStrategyTester = StrategyTester<AsfStrategy>;
Junxiao Shi890afe92016-12-15 14:34:34 +000040NFD_REGISTER_STRATEGY(AsfStrategyTester);
41
Vince Lehman8a4c29e2016-07-11 08:49:35 +000042BOOST_AUTO_TEST_SUITE(Fw)
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040043BOOST_FIXTURE_TEST_SUITE(TestAsfStrategy, GlobalIoTimeFixture)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000044
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040045class AsfGridFixture : public GlobalIoTimeFixture
Vince Lehman8a4c29e2016-07-11 08:49:35 +000046{
47protected:
Davide Pesavento14e71f02019-03-28 17:35:25 -040048 explicit
Saurab Dulal432be572021-01-26 12:09:29 -060049 AsfGridFixture(const Name& params = AsfStrategy::getStrategyName(),
50 time::nanoseconds replyDelay = 0_ns)
Davide Pesavento14e71f02019-03-28 17:35:25 -040051 : parameters(params)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000052 {
53 /*
54 * +---------+
55 * +----->| nodeB |<------+
56 * | +---------+ |
57 * 10ms | | 10ms
58 * v v
59 * +---------+ +---------+
60 * | nodeA | | nodeC |
61 * +---------+ +---------+
62 * ^ ^
63 * 100ms | | 100ms
64 * | +---------+ |
65 * +----->| nodeD |<------+
66 * +---------+
67 */
68
69 nodeA = topo.addForwarder("A");
70 nodeB = topo.addForwarder("B");
71 nodeC = topo.addForwarder("C");
72 nodeD = topo.addForwarder("D");
73
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -040074 for (auto node : {nodeA, nodeB, nodeC, nodeD}) {
75 topo.setStrategy<AsfStrategy>(node, Name("/"), parameters);
76 }
Vince Lehman8a4c29e2016-07-11 08:49:35 +000077
Davide Pesavento14e71f02019-03-28 17:35:25 -040078 linkAB = topo.addLink("AB", 10_ms, {nodeA, nodeB});
79 linkAD = topo.addLink("AD", 100_ms, {nodeA, nodeD});
80 linkBC = topo.addLink("BC", 10_ms, {nodeB, nodeC});
81 linkCD = topo.addLink("CD", 100_ms, {nodeC, nodeD});
Vince Lehman8a4c29e2016-07-11 08:49:35 +000082
83 consumer = topo.addAppFace("c", nodeA);
84 producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
Saurab Dulala6dec222019-04-01 00:15:10 -050085
86 topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, replyDelay);
Vince Lehman8a4c29e2016-07-11 08:49:35 +000087
88 // Register producer prefix on consumer node
89 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 10);
90 topo.registerPrefix(nodeA, linkAD->getFace(nodeA), PRODUCER_PREFIX, 5);
91 }
92
93 void
Saurab Dulal432be572021-01-26 12:09:29 -060094 runConsumer(size_t numInterests = 30)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000095 {
Davide Pesavento14e71f02019-03-28 17:35:25 -040096 topo.addIntervalConsumer(consumer->getClientFace(), PRODUCER_PREFIX, 1_s, numInterests);
97 this->advanceClocks(10_ms, time::seconds(numInterests));
Vince Lehman8a4c29e2016-07-11 08:49:35 +000098 }
99
100protected:
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500101 Name parameters;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000102 TopologyTester topo;
103
104 TopologyNode nodeA;
105 TopologyNode nodeB;
106 TopologyNode nodeC;
107 TopologyNode nodeD;
108
109 shared_ptr<TopologyLink> linkAB;
110 shared_ptr<TopologyLink> linkAD;
111 shared_ptr<TopologyLink> linkBC;
112 shared_ptr<TopologyLink> linkCD;
113
114 shared_ptr<TopologyAppLink> consumer;
115 shared_ptr<TopologyAppLink> producer;
116
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400117 static inline const Name PRODUCER_PREFIX{"/hr/C"};
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000118};
119
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500120class AsfStrategyParametersGridFixture : public AsfGridFixture
121{
122protected:
123 AsfStrategyParametersGridFixture()
124 : AsfGridFixture(Name(AsfStrategy::getStrategyName())
125 .append("probing-interval~30000")
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400126 .append("max-timeouts~5"))
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500127 {
128 }
129};
130
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000131BOOST_FIXTURE_TEST_CASE(Basic, AsfGridFixture)
132{
133 // Both nodeB and nodeD have FIB entries to reach the producer
134 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
135 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
136
137 runConsumer();
138
139 // ASF should use the Face to nodeD because it has lower routing cost.
140 // After 5 seconds, a probe Interest should be sent to the Face to nodeB,
141 // and the probe should return Data quicker. ASF should then use the Face
142 // to nodeB to forward the remaining Interests.
143 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 30);
Alex Lane9cec6992020-03-05 19:10:09 -0600144 // Because of exploration, will forward to AB and AD simultaneously at least once
145 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 25);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000146 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 6);
147
148 // If the link from nodeA to nodeB fails, ASF should start using the Face
149 // to nodeD again.
150 linkAB->fail();
151
152 runConsumer();
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400153 // We experience 3 timeouts and marked AB as timed out
154 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 57);
Alex Lane9cec6992020-03-05 19:10:09 -0600155 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 36);
156 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 24);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000157
158 // If the link from nodeA to nodeB recovers, ASF should probe the Face
159 // to nodeB and start using it again.
160 linkAB->recover();
161
162 // Advance time to ensure probing is due
Davide Pesavento14e71f02019-03-28 17:35:25 -0400163 this->advanceClocks(10_ms, 10_s);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000164
165 runConsumer();
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400166 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 87);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000167 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 50);
168 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 40);
169
170 // If both links fail, nodeA should forward to the next hop with the lowest cost
171 linkAB->fail();
172 linkAD->fail();
173
174 runConsumer();
175
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400176 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 87);
Alex Lane9cec6992020-03-05 19:10:09 -0600177 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 65); // FIXME #3830
178 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 57); // FIXME #3830
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000179}
180
181BOOST_FIXTURE_TEST_CASE(Nack, AsfGridFixture)
182{
183 // nodeB has a FIB entry to reach the producer, but nodeD does not
184 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
185
186 // The strategy should first try to send to nodeD. But since nodeD does not have a route for
187 // the producer's prefix, it should return a NO_ROUTE Nack. The strategy should then start using the Face to
188 // nodeB.
189 runConsumer();
190
191 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nInNacks, 1);
192 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 29);
193 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 29);
194
195 // nodeD should receive 2 Interests: one for the very first Interest and
196 // another from a probe
197 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
198}
199
Saurab Dulala6dec222019-04-01 00:15:10 -0500200class AsfStrategyDelayedDataFixture : public AsfGridFixture
201{
202protected:
203 AsfStrategyDelayedDataFixture()
204 : AsfGridFixture(Name(AsfStrategy::getStrategyName()), 400_ms)
205 {
206 }
207};
208
209BOOST_FIXTURE_TEST_CASE(InterestForwarding, AsfStrategyDelayedDataFixture)
210{
Saurab Dulala6dec222019-04-01 00:15:10 -0500211 Name name(PRODUCER_PREFIX);
212 name.appendTimestamp();
Saurab Dulal432be572021-01-26 12:09:29 -0600213 auto interest = makeInterest(name);
Saurab Dulala6dec222019-04-01 00:15:10 -0500214
215 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
216 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
217
218 // The first interest should go via link AD
219 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
220 this->advanceClocks(10_ms, 100_ms);
221 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 1);
222
223 // Second interest should go via link AB
224 interest->refreshNonce();
225 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
226 this->advanceClocks(10_ms, 100_ms);
227 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 1);
228
229 // The third interest should again go via AD, since both the face from A is already used
230 // and so asf should choose the earliest used face i.e. AD
231 interest->refreshNonce();
232 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
233 this->advanceClocks(10_ms, 100_ms);
234 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
235
236 this->advanceClocks(time::milliseconds(500), time::seconds(5));
237 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nInData, 1);
238 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 1);
239 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 1);
Saurab Dulala6dec222019-04-01 00:15:10 -0500240}
241
Saurab Dulal432be572021-01-26 12:09:29 -0600242BOOST_AUTO_TEST_CASE(Retransmission) // Bug #4874
Saurab Dulala6dec222019-04-01 00:15:10 -0500243{
Saurab Dulala6dec222019-04-01 00:15:10 -0500244 // Avoid clearing pit entry for those incoming interest that have pit entry but no next hops
Saurab Dulal432be572021-01-26 12:09:29 -0600245 /*
246 * +---------+ 10ms +---------+
247 * | nodeB | ------> | nodeC |
248 * +---------+ +---------+
249 */
Saurab Dulala6dec222019-04-01 00:15:10 -0500250
Saurab Dulal432be572021-01-26 12:09:29 -0600251 const Name PRODUCER_PREFIX = "/pnr/C";
Saurab Dulala6dec222019-04-01 00:15:10 -0500252 TopologyTester topo;
253
254 TopologyNode nodeB = topo.addForwarder("B"),
255 nodeC = topo.addForwarder("C");
256
Saurab Dulal432be572021-01-26 12:09:29 -0600257 for (auto node : {nodeB, nodeC}) {
258 topo.setStrategy<AsfStrategy>(node);
259 }
Saurab Dulala6dec222019-04-01 00:15:10 -0500260
Saurab Dulal432be572021-01-26 12:09:29 -0600261 auto linkBC = topo.addLink("BC", time::milliseconds(10), {nodeB, nodeC});
Saurab Dulala6dec222019-04-01 00:15:10 -0500262
Saurab Dulal432be572021-01-26 12:09:29 -0600263 auto consumer = topo.addAppFace("c", nodeB),
264 producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
Saurab Dulala6dec222019-04-01 00:15:10 -0500265
266 topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, 100_ms);
267
268 Name name(PRODUCER_PREFIX);
269 name.appendTimestamp();
Saurab Dulal432be572021-01-26 12:09:29 -0600270 auto interest = makeInterest(name);
Saurab Dulala6dec222019-04-01 00:15:10 -0500271
Saurab Dulal432be572021-01-26 12:09:29 -0600272 auto& pit = topo.getForwarder(nodeB).getPit();
273 auto pitEntry = pit.insert(*interest).first;
Saurab Dulala6dec222019-04-01 00:15:10 -0500274
Davide Pesavento0498ce82021-06-14 02:02:21 -0400275 topo.getForwarder(nodeB).onOutgoingInterest(*interest, linkBC->getFace(nodeB), pitEntry);
Saurab Dulala6dec222019-04-01 00:15:10 -0500276 this->advanceClocks(time::milliseconds(100));
277
278 interest->refreshNonce();
279 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
280 this->advanceClocks(time::milliseconds(100));
281
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500282 auto outRecord = pitEntry->findOutRecord(linkBC->getFace(nodeB));
Saurab Dulala6dec222019-04-01 00:15:10 -0500283 BOOST_CHECK(outRecord != pitEntry->out_end());
284
285 this->advanceClocks(time::milliseconds(100));
286 BOOST_CHECK_EQUAL(linkBC->getFace(nodeC).getCounters().nOutData, 1);
287 BOOST_CHECK_EQUAL(linkBC->getFace(nodeB).getCounters().nInData, 1);
288}
289
Saurab Dulal432be572021-01-26 12:09:29 -0600290BOOST_AUTO_TEST_CASE(PerUpstreamSuppression)
291{
292 /*
293 * +---------+
294 * +----| nodeB |----+
295 * | +---------+ |
296 * 50ms | | 50ms
297 * | |
298 * +---------+ 50ms +---------+
299 * | nodeA | <-----> | nodeP |
300 * +---------+ +---------+
301 */
302
303 const Name PRODUCER_PREFIX = "/suppress/me";
304 TopologyTester topo;
305
306 TopologyNode nodeA = topo.addForwarder("A"),
307 nodeB = topo.addForwarder("B"),
308 nodeP = topo.addForwarder("P");
309
310 for (auto node : {nodeA, nodeB, nodeP}) {
311 topo.setStrategy<AsfStrategy>(node);
312 }
313
314 auto linkAB = topo.addLink("AB", 50_ms, {nodeA, nodeB});
315 auto linkAP = topo.addLink("AP", 50_ms, {nodeA, nodeP});
316 auto linkBP = topo.addLink("BP", 50_ms, {nodeB, nodeP});
317
318 auto consumer = topo.addAppFace("cons", nodeA),
319 producer = topo.addAppFace("prod", nodeP, PRODUCER_PREFIX);
320
321 topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX);
322
323 topo.registerPrefix(nodeA, linkAP->getFace(nodeA), PRODUCER_PREFIX, 10);
324 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 1);
325 topo.registerPrefix(nodeB, linkBP->getFace(nodeB), PRODUCER_PREFIX, 1);
326
327 auto& faceA2B = linkAB->getFace(nodeA);
328 auto& faceA2P = linkAP->getFace(nodeA);
329
330 Name name(PRODUCER_PREFIX);
331 name.appendTimestamp();
332 // very short lifetime to make it expire within the initial retx suppression period (10ms)
333 auto interest = makeInterest(name, false, 5_ms);
334
335 // 1st interest should be sent to B
336 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
337 this->advanceClocks(1_ms);
338 BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
339 BOOST_TEST(faceA2P.getCounters().nOutInterests == 0);
340
341 // 2nd interest should be sent to P and NOT suppressed
342 interest->setInterestLifetime(100_ms);
343 interest->refreshNonce();
344 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
345 this->advanceClocks(1_ms);
346 BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
347 BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);
348
349 this->advanceClocks(1_ms);
350
351 // 3rd interest should be suppressed
352 // without suppression, it would have been sent again to B as that's the earliest out-record
353 interest->refreshNonce();
354 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
355 this->advanceClocks(1_ms);
356 BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
357 BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);
358
359 this->advanceClocks(2_ms); // 1st interest should expire now
360
361 // 4th interest should be suppressed
362 // without suppression, it would have been sent again to B because the out-record expired
363 interest->refreshNonce();
364 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
365 this->advanceClocks(1_ms);
366 BOOST_TEST(faceA2B.getCounters().nOutInterests == 1);
367 BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);
368
369 this->advanceClocks(5_ms); // suppression window ends
370
371 // 5th interest is sent to B and is outside the suppression window
372 interest->refreshNonce();
373 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
374 this->advanceClocks(1_ms);
375 BOOST_TEST(faceA2B.getCounters().nOutInterests == 2);
376 BOOST_TEST(faceA2P.getCounters().nOutInterests == 1);
377
378 this->advanceClocks(10_ms);
379
380 // 6th interest is sent to P and is outside the suppression window
381 interest->refreshNonce();
382 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
383 this->advanceClocks(1_ms);
384 BOOST_TEST(faceA2B.getCounters().nOutInterests == 2);
385 BOOST_TEST(faceA2P.getCounters().nOutInterests == 2);
386}
387
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000388BOOST_AUTO_TEST_CASE(NoPitOutRecordAndProbeInterestNewNonce)
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600389{
Saurab Dulal432be572021-01-26 12:09:29 -0600390 /* +---------+
391 * | nodeD |
392 * +---------+
393 * |
394 * | 80ms
395 * |
396 * |
397 * +---------+
398 * +----->| nodeB |<------+
399 * | +---------+ |
400 * 15ms | | 16ms
401 * v v
402 * +---------+ +---------+
403 * | nodeA |--------------| nodeC |
404 * +---------+ 14ms +---------+
405 */
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600406
407 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600408 TopologyTester topo;
Saurab Dulal432be572021-01-26 12:09:29 -0600409
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600410 TopologyNode nodeA = topo.addForwarder("A"),
411 nodeB = topo.addForwarder("B"),
412 nodeC = topo.addForwarder("C"),
413 nodeD = topo.addForwarder("D");
414
Saurab Dulal432be572021-01-26 12:09:29 -0600415 for (auto node : {nodeA, nodeB, nodeC, nodeD}) {
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500416 topo.setStrategy<AsfStrategy>(node);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600417 }
418
Saurab Dulal432be572021-01-26 12:09:29 -0600419 auto linkAB = topo.addLink("AB", 15_ms, {nodeA, nodeB}),
420 linkAC = topo.addLink("AC", 14_ms, {nodeA, nodeC}),
421 linkBC = topo.addLink("BC", 16_ms, {nodeB, nodeC}),
422 linkBD = topo.addLink("BD", 80_ms, {nodeB, nodeD});
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600423
Saurab Dulal432be572021-01-26 12:09:29 -0600424 auto ping = topo.addAppFace("c", nodeA);
425 auto pingServer = topo.addAppFace("p", nodeD, PRODUCER_PREFIX);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600426 topo.addEchoProducer(pingServer->getClientFace());
427
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600428 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 15);
429 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 14);
430 topo.registerPrefix(nodeC, linkBC->getFace(nodeC), PRODUCER_PREFIX, 16);
431 topo.registerPrefix(nodeB, linkBD->getFace(nodeB), PRODUCER_PREFIX, 80);
432
433 // Send 6 interest since probes can be scheduled b/w 0-5 seconds
434 for (int i = 1; i < 7; i++) {
435 // Send ping number i
436 Name name(PRODUCER_PREFIX);
437 name.appendTimestamp();
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400438 auto interest = makeInterest(name);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600439 ping->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400440 auto nonce = interest->getNonce();
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600441
442 // Don't know when the probe will be triggered since it is random between 0-5 seconds
443 // or whether it will be triggered for this interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400444 for (int j = 1; j <= 1000 && linkAB->getFace(nodeA).getCounters().nOutInterests != 1; ++j) {
445 this->advanceClocks(1_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600446 }
447
448 // Check if probe is sent to B else send another ping
449 if (linkAB->getFace(nodeA).getCounters().nOutInterests == 1) {
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000450 // Get pitEntry of node A
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400451 auto pitEntry = topo.getForwarder(nodeA).getPit().find(*interest);
452 // Get outRecord associated with face towards B
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500453 auto outRecord = pitEntry->findOutRecord(linkAB->getFace(nodeA));
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400454 BOOST_REQUIRE(outRecord != pitEntry->out_end());
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000455
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400456 // Check that Nonce of interest is not equal to Nonce of Probe
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000457 BOOST_CHECK_NE(nonce, outRecord->getLastNonce());
458
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600459 // B should not have received the probe interest yet
460 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 0);
461
462 // i-1 interests through B when no probe
463 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i - 1);
464
465 // After 15ms, B should get the probe interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400466 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600467 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 1);
468 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i);
469
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000470 pitEntry = topo.getForwarder(nodeB).getPit().find(*interest);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600471
472 // Get outRecord associated with face towards D.
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500473 outRecord = pitEntry->findOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600474 BOOST_CHECK(outRecord != pitEntry->out_end());
475
476 // RTT between B and D
Davide Pesavento14e71f02019-03-28 17:35:25 -0400477 this->advanceClocks(5_ms, 160_ms);
Davide Pesaventob124b8e2024-02-16 16:54:26 -0500478 outRecord = pitEntry->findOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600479
480 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i);
481
482 BOOST_CHECK(outRecord == pitEntry->out_end());
483
484 // Data is returned for the ping after 15 ms - will result in false measurement
485 // 14+16-15 = 15ms
486 // Since outRecord == pitEntry->out_end()
Davide Pesavento14e71f02019-03-28 17:35:25 -0400487 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600488 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i+1);
489
490 break;
491 }
492 }
493}
494
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500495BOOST_FIXTURE_TEST_CASE(IgnoreTimeouts, AsfStrategyParametersGridFixture)
496{
497 // Both nodeB and nodeD have FIB entries to reach the producer
498 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
499 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
500
501 // Send 15 interests let it change to use the 10 ms link
502 runConsumer(15);
503
Saurab Dulal432be572021-01-26 12:09:29 -0600504 uint64_t outInterestsBeforeFailure = linkAD->getFace(nodeA).getCounters().nOutInterests;
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500505
506 // Bring down 10 ms link
507 linkAB->fail();
508
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400509 // Send 5 interests, after the last one it will record the timeout
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500510 // ready to switch for the next interest
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400511 runConsumer(5);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500512
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400513 // Check that link has not been switched to 100 ms because max-timeouts = 5
Saurab Dulal432be572021-01-26 12:09:29 -0600514 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, outInterestsBeforeFailure);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500515
516 // Send 5 interests, check that 100 ms link is used
517 runConsumer(5);
518
Saurab Dulal432be572021-01-26 12:09:29 -0600519 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, outInterestsBeforeFailure + 5);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500520}
521
522BOOST_FIXTURE_TEST_CASE(ProbingInterval, AsfStrategyParametersGridFixture)
523{
524 // Both nodeB and nodeD have FIB entries to reach the producer
525 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
526 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
527
528 // Send 6 interests let it change to use the 10 ms link
529 runConsumer(6);
530
Saurab Dulal432be572021-01-26 12:09:29 -0600531 auto linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeD});
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500532 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 1);
533
534 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 0);
535
536 // After 30 seconds a probe would be sent that would switch make ASF switch
537 runConsumer(30);
538
539 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 1);
540}
541
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400542BOOST_AUTO_TEST_CASE(Parameters)
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500543{
Saurab Dulal432be572021-01-26 12:09:29 -0600544 FaceTable faceTable;
545 Forwarder forwarder{faceTable};
546
Davide Pesaventod7083a52023-10-19 17:51:16 -0400547 auto checkValidity = [&] (std::string_view parameters, bool isCorrect) {
548 BOOST_TEST_INFO_SCOPE(parameters);
549 Name strategyName(Name(AsfStrategy::getStrategyName()).append(Name(parameters)));
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400550 std::unique_ptr<AsfStrategy> strategy;
Davide Pesaventod7083a52023-10-19 17:51:16 -0400551 if (isCorrect) {
552 strategy = make_unique<AsfStrategy>(forwarder, strategyName);
553 BOOST_CHECK(strategy->m_retxSuppression != nullptr);
554 }
555 else {
556 BOOST_CHECK_THROW(make_unique<AsfStrategy>(forwarder, strategyName), std::invalid_argument);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500557 }
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400558 return strategy;
Saurab Dulal432be572021-01-26 12:09:29 -0600559 };
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500560
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400561 auto strategy = checkValidity("", true);
562 BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
563 BOOST_TEST(strategy->m_nMaxTimeouts == 3);
awlaneee97f532024-09-19 15:48:21 -0500564 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
565 strategy = checkValidity("/probing-interval~30000/max-timeouts~5/measurements-lifetime~120000", true);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400566 BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
567 BOOST_TEST(strategy->m_nMaxTimeouts == 5);
awlaneee97f532024-09-19 15:48:21 -0500568 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400569 strategy = checkValidity("/max-timeouts~5/probing-interval~30000", true);
570 BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
571 BOOST_TEST(strategy->m_nMaxTimeouts == 5);
awlaneee97f532024-09-19 15:48:21 -0500572 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
573 strategy = checkValidity("/max-timeouts~5/measurements-lifetime~120000", true);
574 BOOST_TEST(strategy->m_nMaxTimeouts == 5);
575 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
576 strategy = checkValidity("/probing-interval~30000/measurements-lifetime~120000", true);
577 BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
578 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400579 strategy = checkValidity("/probing-interval~1000", true);
580 BOOST_TEST(strategy->m_probing.getProbingInterval() == 1_s);
581 BOOST_TEST(strategy->m_nMaxTimeouts == 3);
awlaneee97f532024-09-19 15:48:21 -0500582 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400583 strategy = checkValidity("/max-timeouts~0", true);
584 BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
585 BOOST_TEST(strategy->m_nMaxTimeouts == 0);
awlaneee97f532024-09-19 15:48:21 -0500586 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 5_min);
587 strategy = checkValidity("/measurements-lifetime~120000", true);
588 BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
589 BOOST_TEST(strategy->m_nMaxTimeouts == 3);
590 BOOST_TEST(strategy->m_measurements.getMeasurementsLifetime() == 2_min);
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400591 BOOST_TEST(strategy->m_retxSuppression->m_initialInterval == fw::RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL);
592 BOOST_TEST(strategy->m_retxSuppression->m_maxInterval == fw::RetxSuppressionExponential::DEFAULT_MAX_INTERVAL);
593 BOOST_TEST(strategy->m_retxSuppression->m_multiplier == fw::RetxSuppressionExponential::DEFAULT_MULTIPLIER);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500594
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400595 checkValidity("/probing-interval~500", false); // minimum is 1 second
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500596 checkValidity("/probing-interval~-5000", false);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400597 checkValidity("/max-timeouts~-1", false);
598 checkValidity("/max-timeouts~ -1", false);
599 checkValidity("/max-timeouts~1-0", false);
600 checkValidity("/max-timeouts~1/probing-interval~-30000", false);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500601 checkValidity("/probing-interval~foo", false);
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400602 checkValidity("/max-timeouts~1~2", false);
awlaneee97f532024-09-19 15:48:21 -0500603 checkValidity("/measurements-lifetime~1000", false); //Minimum is 60s by default
604 //Measurement lifetime must be greater than probing interval
605 checkValidity("/measurements-lifetime~1000/probing-interval~30000", false);
606 checkValidity("/measurements-lifetime~-120000", false);
607 checkValidity("/measurements-lifetime~ -120000", false);
608 checkValidity("/measurements-lifetime~0-120000", false);
609 checkValidity("/max-timeouts~1/measurements-lifetime~-120000", false);
610 checkValidity("/probing-interval~30000/measurements-lifetime~-120000", false);
611 checkValidity("/max-timeouts~1/probing-interval~30000/measurements-lifetime~-120000", false);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500612}
613
awlane5fdcbec2023-12-15 14:56:05 -0600614BOOST_AUTO_TEST_CASE(FaceRankingForForwarding)
615{
616 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
617 AsfStrategy::FaceStatsForwardingSet rankedFaces;
618
619 //Group 1- Working Measured Faces
620 FaceInfo group1_a(nullptr);
621 group1_a.recordRtt(25_ms);
622 DummyFace face1_a;
623 face1_a.setId(1);
624 rankedFaces.insert({&face1_a, group1_a.getLastRtt(), group1_a.getSrtt(), 0});
625 // Higher FaceId
626 FaceInfo group1_b(nullptr);
627 group1_b.recordRtt(25_ms);
628 DummyFace face1_b;
629 face1_b.setId(2);
630 rankedFaces.insert({&face1_b, group1_b.getLastRtt(), group1_b.getSrtt(), 0});
631 //Higher SRTT
632 FaceInfo group1_c(nullptr);
633 group1_c.recordRtt(30_ms);
634 DummyFace face1_c;
635 face1_c.setId(3);
636 rankedFaces.insert({&face1_c, group1_c.getLastRtt(), group1_c.getSrtt(), 0});
637 //Higher SRTT/Cost
638 FaceInfo group1_d(nullptr);
639 group1_d.recordRtt(30_ms);
640 DummyFace face1_d;
641 face1_d.setId(4);
642 rankedFaces.insert({&face1_d, group1_d.getLastRtt(), group1_d.getSrtt(), 1});
643 //Group 2- Unmeasured Faces
644 FaceInfo group2_a(nullptr);
645 DummyFace face2_a;
646 face2_a.setId(5);
647 rankedFaces.insert({&face2_a, FaceInfo::RTT_NO_MEASUREMENT,
648 FaceInfo::RTT_NO_MEASUREMENT, 0});
649 //Higher FaceId
650 FaceInfo group2_b(nullptr);
651 DummyFace face2_b;
652 face2_b.setId(6);
653 rankedFaces.insert({&face2_b, FaceInfo::RTT_NO_MEASUREMENT,
654 FaceInfo::RTT_NO_MEASUREMENT, 0});
655 //Higher Cost
656 FaceInfo group2_c(nullptr);
657 DummyFace face2_c;
658 face2_c.setId(7);
659 rankedFaces.insert({&face2_c, FaceInfo::RTT_NO_MEASUREMENT,
660 FaceInfo::RTT_NO_MEASUREMENT, 1});
661 //Group 3- Timeout Faces
662 //Lowest cost, high SRTT
663 FaceInfo group3_a(nullptr);
664 group3_a.recordRtt(30_ms);
665 group3_a.recordTimeout(PRODUCER_PREFIX);
666 DummyFace face3_a;
667 face3_a.setId(8);
668 rankedFaces.insert({&face3_a, group3_a.getLastRtt(), group3_a.getSrtt(), 0});
669 //Lowest cost, lower SRTT, higher FaceId
670 FaceInfo group3_b(nullptr);
671 group3_b.recordRtt(30_ms);
672 group3_b.recordTimeout(PRODUCER_PREFIX);
673 DummyFace face3_b;
674 face3_b.setId(9);
675 rankedFaces.insert({&face3_b, group3_b.getLastRtt(), group3_b.getSrtt(), 0});
676 //Lowest cost, higher SRTT, higher FaceId
677 FaceInfo group3_c(nullptr);
678 group3_c.recordRtt(45_ms);
679 group3_c.recordTimeout(PRODUCER_PREFIX);
680 DummyFace face3_c;
681 face3_c.setId(10);
682 rankedFaces.insert({&face3_c, group3_c.getLastRtt(), group3_c.getSrtt(), 0});
683 //Lowest cost, no SRTT, higher FaceId
684 FaceInfo group3_d(nullptr);
685 group3_d.recordTimeout(PRODUCER_PREFIX);
686 DummyFace face3_d;
687 face3_d.setId(11);
688 rankedFaces.insert({&face3_d, group3_d.getLastRtt(), FaceInfo::RTT_NO_MEASUREMENT, 0});
689 //Higher cost, lower SRTT, higher FaceId
690 FaceInfo group3_e(nullptr);
691 group3_e.recordRtt(15_ms);
692 group3_e.recordTimeout(PRODUCER_PREFIX);
693 DummyFace face3_e;
694 face3_e.setId(12);
695 rankedFaces.insert({&face3_e, group3_e.getLastRtt(), group3_e.getSrtt(), 1});
696 //Higher cost, higher SRTT, higher FaceId
697 FaceInfo group3_f(nullptr);
698 group3_f.recordRtt(45_ms);
699 group3_f.recordTimeout(PRODUCER_PREFIX);
700 DummyFace face3_f;
701 face3_f.setId(13);
702 rankedFaces.insert({&face3_f, group3_f.getLastRtt(), group3_f.getSrtt(), 1});
703 //Higher cost, no SRTT, higher FaceId
704 FaceInfo group3_g(nullptr);
705 group3_g.recordTimeout(PRODUCER_PREFIX);
706 DummyFace face3_g;
707 face3_g.setId(14);
708 rankedFaces.insert({&face3_g, FaceInfo::RTT_TIMEOUT,
709 FaceInfo::RTT_NO_MEASUREMENT, 1});
710 auto face = rankedFaces.begin();
711 //Group 1 - Working Measured Faces
712 BOOST_CHECK_EQUAL(face->rtt, group1_a.getLastRtt());
713 BOOST_CHECK_EQUAL(face->srtt, group1_a.getSrtt());
714 BOOST_CHECK_EQUAL(face->face->getId(), 1);
715 face++;
716 BOOST_CHECK_EQUAL(face->rtt, group1_b.getLastRtt());
717 BOOST_CHECK_EQUAL(face->srtt, group1_b.getSrtt());
718 BOOST_CHECK_EQUAL(face->face->getId(), 2);
719 face++;
720 BOOST_CHECK_EQUAL(face->rtt, group1_c.getLastRtt());
721 BOOST_CHECK_EQUAL(face->srtt, group1_c.getSrtt());
722 BOOST_CHECK_EQUAL(face->face->getId(), 3);
723 face++;
724 BOOST_CHECK_EQUAL(face->rtt, group1_d.getLastRtt());
725 BOOST_CHECK_EQUAL(face->srtt, group1_d.getSrtt());
726 BOOST_CHECK_EQUAL(face->face->getId(), 4);
727 face++;
728 //Group 2 - Unmeasured Faces
729 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
730 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
731 BOOST_CHECK_EQUAL(face->face->getId(), 5);
732 face++;
733 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
734 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
735 BOOST_CHECK_EQUAL(face->face->getId(), 6);
736 face++;
737 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
738 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
739 BOOST_CHECK_EQUAL(face->face->getId(), 7);
740 face++;
741 //Group 3 - Timeout
742 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
743 BOOST_CHECK_EQUAL(face->srtt, group3_a.getSrtt());
744 BOOST_CHECK_EQUAL(face->face->getId(), 8);
745 face++;
746 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
747 BOOST_CHECK_EQUAL(face->srtt, group3_b.getSrtt());
748 BOOST_CHECK_EQUAL(face->face->getId(), 9);
749 face++;
750 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
751 BOOST_CHECK_EQUAL(face->srtt, group3_c.getSrtt());
752 BOOST_CHECK_EQUAL(face->face->getId(), 10);
753 face++;
754 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
755 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
756 BOOST_CHECK_EQUAL(face->face->getId(), 11);
757 face++;
758 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
759 BOOST_CHECK_EQUAL(face->srtt, group3_e.getSrtt());
760 BOOST_CHECK_EQUAL(face->face->getId(), 12);
761 face++;
762 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
763 BOOST_CHECK_EQUAL(face->srtt, group3_f.getSrtt());
764 BOOST_CHECK_EQUAL(face->face->getId(), 13);
765 face++;
766 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
767 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
768 BOOST_CHECK_EQUAL(face->face->getId(), 14);
769 // face++;
770}
771
772BOOST_AUTO_TEST_CASE(FaceRankingForProbing)
773{
774 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
775 fw::asf::ProbingModule::FaceStatsProbingSet rankedFaces;
776
777 //Group 2- Unmeasured Faces
778 FaceInfo group2_a(nullptr);
779 DummyFace face2_a;
780 face2_a.setId(1);
781 rankedFaces.insert({&face2_a, FaceInfo::RTT_NO_MEASUREMENT,
782 FaceInfo::RTT_NO_MEASUREMENT, 0});
783 //Higher FaceId
784 FaceInfo group2_b(nullptr);
785 DummyFace face2_b;
786 face2_b.setId(2);
787 rankedFaces.insert({&face2_b, FaceInfo::RTT_NO_MEASUREMENT,
788 FaceInfo::RTT_NO_MEASUREMENT, 0});
789 //Higher Cost
790 FaceInfo group2_c(nullptr);
791 DummyFace face2_c;
792 face2_c.setId(3);
793 rankedFaces.insert({&face2_c, FaceInfo::RTT_NO_MEASUREMENT,
794 FaceInfo::RTT_NO_MEASUREMENT, 1});
795
796 //Group 1- Working Measured Faces
797 FaceInfo group1_a(nullptr);
798 group1_a.recordRtt(25_ms);
799 DummyFace face1_a;
800 face1_a.setId(4);
801 rankedFaces.insert({&face1_a, group1_a.getLastRtt(), group1_a.getSrtt(), 0});
802 // Higher FaceId
803 FaceInfo group1_b(nullptr);
804 group1_b.recordRtt(25_ms);
805 DummyFace face1_b;
806 face1_b.setId(5);
807 rankedFaces.insert({&face1_b, group1_b.getLastRtt(), group1_b.getSrtt(), 0});
808 //Higher SRTT
809 FaceInfo group1_c(nullptr);
810 group1_c.recordRtt(30_ms);
811 DummyFace face1_c;
812 face1_c.setId(6);
813 rankedFaces.insert({&face1_c, group1_c.getLastRtt(), group1_c.getSrtt(), 0});
814 //Higher SRTT/Cost
815 FaceInfo group1_d(nullptr);
816 group1_d.recordRtt(30_ms);
817 DummyFace face1_d;
818 face1_d.setId(7);
819 rankedFaces.insert({&face1_d, group1_d.getLastRtt(), group1_d.getSrtt(), 1});
820
821 //Group 3- Timeout Faces
822 //Lowest cost, high SRTT
823 FaceInfo group3_a(nullptr);
824 group3_a.recordRtt(30_ms);
825 group3_a.recordTimeout(PRODUCER_PREFIX);
826 DummyFace face3_a;
827 face3_a.setId(8);
828 rankedFaces.insert({&face3_a, group3_a.getLastRtt(), group3_a.getSrtt(), 0});
829 //Lowest cost, lower SRTT, higher FaceId
830 FaceInfo group3_b(nullptr);
831 group3_b.recordRtt(30_ms);
832 group3_b.recordTimeout(PRODUCER_PREFIX);
833 DummyFace face3_b;
834 face3_b.setId(9);
835 rankedFaces.insert({&face3_b, group3_b.getLastRtt(), group3_b.getSrtt(), 0});
836 //Lowest cost, higher SRTT, higher FaceId
837 FaceInfo group3_c(nullptr);
838 group3_c.recordRtt(45_ms);
839 group3_c.recordTimeout(PRODUCER_PREFIX);
840 DummyFace face3_c;
841 face3_c.setId(10);
842 rankedFaces.insert({&face3_c, group3_c.getLastRtt(), group3_c.getSrtt(), 0});
843 //Lowest cost, no SRTT, higher FaceId
844 FaceInfo group3_d(nullptr);
845 group3_d.recordTimeout(PRODUCER_PREFIX);
846 DummyFace face3_d;
847 face3_d.setId(11);
848 rankedFaces.insert({&face3_d, group3_d.getLastRtt(), FaceInfo::RTT_NO_MEASUREMENT, 0});
849 //Higher cost, lower SRTT, higher FaceId
850 FaceInfo group3_e(nullptr);
851 group3_e.recordRtt(15_ms);
852 group3_e.recordTimeout(PRODUCER_PREFIX);
853 DummyFace face3_e;
854 face3_e.setId(12);
855 rankedFaces.insert({&face3_e, group3_e.getLastRtt(), group3_e.getSrtt(), 1});
856 //Higher cost, higher SRTT, higher FaceId
857 FaceInfo group3_f(nullptr);
858 group3_f.recordRtt(45_ms);
859 group3_f.recordTimeout(PRODUCER_PREFIX);
860 DummyFace face3_f;
861 face3_f.setId(13);
862 rankedFaces.insert({&face3_f, group3_f.getLastRtt(), group3_f.getSrtt(), 1});
863 //Higher cost, no SRTT, higher FaceId
864 FaceInfo group3_g(nullptr);
865 group3_g.recordTimeout(PRODUCER_PREFIX);
866 DummyFace face3_g;
867 face3_g.setId(14);
868 rankedFaces.insert({&face3_g, group3_g.getLastRtt(),
869 FaceInfo::RTT_NO_MEASUREMENT, 1});
870 auto face = rankedFaces.begin();
871
872 //Group 2 - Unmeasured Faces
873 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
874 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
875 BOOST_CHECK_EQUAL(face->face->getId(), 1);
876 face++;
877 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
878 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
879 BOOST_CHECK_EQUAL(face->face->getId(), 2);
880 face++;
881 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
882 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
883 BOOST_CHECK_EQUAL(face->face->getId(), 3);
884 face++;
885 //Group 1 - Working Measured Faces
886 BOOST_CHECK_EQUAL(face->rtt, group1_a.getLastRtt());
887 BOOST_CHECK_EQUAL(face->srtt, group1_a.getSrtt());
888 BOOST_CHECK_EQUAL(face->face->getId(), 4);
889 face++;
890 BOOST_CHECK_EQUAL(face->rtt, group1_b.getLastRtt());
891 BOOST_CHECK_EQUAL(face->srtt, group1_b.getSrtt());
892 BOOST_CHECK_EQUAL(face->face->getId(), 5);
893 face++;
894 BOOST_CHECK_EQUAL(face->rtt, group1_c.getLastRtt());
895 BOOST_CHECK_EQUAL(face->srtt, group1_c.getSrtt());
896 BOOST_CHECK_EQUAL(face->face->getId(), 6);
897 face++;
898 BOOST_CHECK_EQUAL(face->rtt, group1_d.getLastRtt());
899 BOOST_CHECK_EQUAL(face->srtt, group1_d.getSrtt());
900 BOOST_CHECK_EQUAL(face->face->getId(), 7);
901 face++;
902 //Group 3 - Timeout
903 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
904 BOOST_CHECK_EQUAL(face->srtt, group3_a.getSrtt());
905 BOOST_CHECK_EQUAL(face->face->getId(), 8);
906 face++;
907 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
908 BOOST_CHECK_EQUAL(face->srtt, group3_b.getSrtt());
909 BOOST_CHECK_EQUAL(face->face->getId(), 9);
910 face++;
911 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
912 BOOST_CHECK_EQUAL(face->srtt, group3_c.getSrtt());
913 BOOST_CHECK_EQUAL(face->face->getId(), 10);
914 face++;
915 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
916 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
917 BOOST_CHECK_EQUAL(face->face->getId(), 11);
918 face++;
919 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
920 BOOST_CHECK_EQUAL(face->srtt, group3_e.getSrtt());
921 BOOST_CHECK_EQUAL(face->face->getId(), 12);
922 face++;
923 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
924 BOOST_CHECK_EQUAL(face->srtt, group3_f.getSrtt());
925 BOOST_CHECK_EQUAL(face->face->getId(), 13);
926 face++;
927 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
928 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
929 BOOST_CHECK_EQUAL(face->face->getId(), 14);
930 // face++;
931}
932
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000933BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
934BOOST_AUTO_TEST_SUITE_END() // Fw
935
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400936} // namespace nfd::tests