blob: 0fde3a5449860d24c7ab93a2e29c38ccbfa3347c [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
Saurab Dulal432be572021-01-26 12:09:29 -0600282 auto outRecord = pitEntry->getOutRecord(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
453 auto outRecord = pitEntry->getOutRecord(linkAB->getFace(nodeA));
454 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.
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000473 outRecord = pitEntry->getOutRecord(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);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000478 outRecord = pitEntry->getOutRecord(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);
564 strategy = checkValidity("/probing-interval~30000/max-timeouts~5", true);
565 BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
566 BOOST_TEST(strategy->m_nMaxTimeouts == 5);
567 strategy = checkValidity("/max-timeouts~5/probing-interval~30000", true);
568 BOOST_TEST(strategy->m_probing.getProbingInterval() == 30_s);
569 BOOST_TEST(strategy->m_nMaxTimeouts == 5);
570 strategy = checkValidity("/probing-interval~1000", true);
571 BOOST_TEST(strategy->m_probing.getProbingInterval() == 1_s);
572 BOOST_TEST(strategy->m_nMaxTimeouts == 3);
573 strategy = checkValidity("/max-timeouts~0", true);
574 BOOST_TEST(strategy->m_probing.getProbingInterval() == 60_s);
575 BOOST_TEST(strategy->m_nMaxTimeouts == 0);
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400576 BOOST_TEST(strategy->m_retxSuppression->m_initialInterval == fw::RetxSuppressionExponential::DEFAULT_INITIAL_INTERVAL);
577 BOOST_TEST(strategy->m_retxSuppression->m_maxInterval == fw::RetxSuppressionExponential::DEFAULT_MAX_INTERVAL);
578 BOOST_TEST(strategy->m_retxSuppression->m_multiplier == fw::RetxSuppressionExponential::DEFAULT_MULTIPLIER);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500579
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400580 checkValidity("/probing-interval~500", false); // minimum is 1 second
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500581 checkValidity("/probing-interval~-5000", false);
Ashlesh Gawande1ef93d02022-04-08 00:25:06 -0400582 checkValidity("/max-timeouts~-1", false);
583 checkValidity("/max-timeouts~ -1", false);
584 checkValidity("/max-timeouts~1-0", false);
585 checkValidity("/max-timeouts~1/probing-interval~-30000", false);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500586 checkValidity("/probing-interval~foo", false);
Saurab Dulalaf3ff5a2021-09-19 19:45:07 -0400587 checkValidity("/max-timeouts~1~2", false);
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500588}
589
awlane5fdcbec2023-12-15 14:56:05 -0600590BOOST_AUTO_TEST_CASE(FaceRankingForForwarding)
591{
592 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
593 AsfStrategy::FaceStatsForwardingSet rankedFaces;
594
595 //Group 1- Working Measured Faces
596 FaceInfo group1_a(nullptr);
597 group1_a.recordRtt(25_ms);
598 DummyFace face1_a;
599 face1_a.setId(1);
600 rankedFaces.insert({&face1_a, group1_a.getLastRtt(), group1_a.getSrtt(), 0});
601 // Higher FaceId
602 FaceInfo group1_b(nullptr);
603 group1_b.recordRtt(25_ms);
604 DummyFace face1_b;
605 face1_b.setId(2);
606 rankedFaces.insert({&face1_b, group1_b.getLastRtt(), group1_b.getSrtt(), 0});
607 //Higher SRTT
608 FaceInfo group1_c(nullptr);
609 group1_c.recordRtt(30_ms);
610 DummyFace face1_c;
611 face1_c.setId(3);
612 rankedFaces.insert({&face1_c, group1_c.getLastRtt(), group1_c.getSrtt(), 0});
613 //Higher SRTT/Cost
614 FaceInfo group1_d(nullptr);
615 group1_d.recordRtt(30_ms);
616 DummyFace face1_d;
617 face1_d.setId(4);
618 rankedFaces.insert({&face1_d, group1_d.getLastRtt(), group1_d.getSrtt(), 1});
619 //Group 2- Unmeasured Faces
620 FaceInfo group2_a(nullptr);
621 DummyFace face2_a;
622 face2_a.setId(5);
623 rankedFaces.insert({&face2_a, FaceInfo::RTT_NO_MEASUREMENT,
624 FaceInfo::RTT_NO_MEASUREMENT, 0});
625 //Higher FaceId
626 FaceInfo group2_b(nullptr);
627 DummyFace face2_b;
628 face2_b.setId(6);
629 rankedFaces.insert({&face2_b, FaceInfo::RTT_NO_MEASUREMENT,
630 FaceInfo::RTT_NO_MEASUREMENT, 0});
631 //Higher Cost
632 FaceInfo group2_c(nullptr);
633 DummyFace face2_c;
634 face2_c.setId(7);
635 rankedFaces.insert({&face2_c, FaceInfo::RTT_NO_MEASUREMENT,
636 FaceInfo::RTT_NO_MEASUREMENT, 1});
637 //Group 3- Timeout Faces
638 //Lowest cost, high SRTT
639 FaceInfo group3_a(nullptr);
640 group3_a.recordRtt(30_ms);
641 group3_a.recordTimeout(PRODUCER_PREFIX);
642 DummyFace face3_a;
643 face3_a.setId(8);
644 rankedFaces.insert({&face3_a, group3_a.getLastRtt(), group3_a.getSrtt(), 0});
645 //Lowest cost, lower SRTT, higher FaceId
646 FaceInfo group3_b(nullptr);
647 group3_b.recordRtt(30_ms);
648 group3_b.recordTimeout(PRODUCER_PREFIX);
649 DummyFace face3_b;
650 face3_b.setId(9);
651 rankedFaces.insert({&face3_b, group3_b.getLastRtt(), group3_b.getSrtt(), 0});
652 //Lowest cost, higher SRTT, higher FaceId
653 FaceInfo group3_c(nullptr);
654 group3_c.recordRtt(45_ms);
655 group3_c.recordTimeout(PRODUCER_PREFIX);
656 DummyFace face3_c;
657 face3_c.setId(10);
658 rankedFaces.insert({&face3_c, group3_c.getLastRtt(), group3_c.getSrtt(), 0});
659 //Lowest cost, no SRTT, higher FaceId
660 FaceInfo group3_d(nullptr);
661 group3_d.recordTimeout(PRODUCER_PREFIX);
662 DummyFace face3_d;
663 face3_d.setId(11);
664 rankedFaces.insert({&face3_d, group3_d.getLastRtt(), FaceInfo::RTT_NO_MEASUREMENT, 0});
665 //Higher cost, lower SRTT, higher FaceId
666 FaceInfo group3_e(nullptr);
667 group3_e.recordRtt(15_ms);
668 group3_e.recordTimeout(PRODUCER_PREFIX);
669 DummyFace face3_e;
670 face3_e.setId(12);
671 rankedFaces.insert({&face3_e, group3_e.getLastRtt(), group3_e.getSrtt(), 1});
672 //Higher cost, higher SRTT, higher FaceId
673 FaceInfo group3_f(nullptr);
674 group3_f.recordRtt(45_ms);
675 group3_f.recordTimeout(PRODUCER_PREFIX);
676 DummyFace face3_f;
677 face3_f.setId(13);
678 rankedFaces.insert({&face3_f, group3_f.getLastRtt(), group3_f.getSrtt(), 1});
679 //Higher cost, no SRTT, higher FaceId
680 FaceInfo group3_g(nullptr);
681 group3_g.recordTimeout(PRODUCER_PREFIX);
682 DummyFace face3_g;
683 face3_g.setId(14);
684 rankedFaces.insert({&face3_g, FaceInfo::RTT_TIMEOUT,
685 FaceInfo::RTT_NO_MEASUREMENT, 1});
686 auto face = rankedFaces.begin();
687 //Group 1 - Working Measured Faces
688 BOOST_CHECK_EQUAL(face->rtt, group1_a.getLastRtt());
689 BOOST_CHECK_EQUAL(face->srtt, group1_a.getSrtt());
690 BOOST_CHECK_EQUAL(face->face->getId(), 1);
691 face++;
692 BOOST_CHECK_EQUAL(face->rtt, group1_b.getLastRtt());
693 BOOST_CHECK_EQUAL(face->srtt, group1_b.getSrtt());
694 BOOST_CHECK_EQUAL(face->face->getId(), 2);
695 face++;
696 BOOST_CHECK_EQUAL(face->rtt, group1_c.getLastRtt());
697 BOOST_CHECK_EQUAL(face->srtt, group1_c.getSrtt());
698 BOOST_CHECK_EQUAL(face->face->getId(), 3);
699 face++;
700 BOOST_CHECK_EQUAL(face->rtt, group1_d.getLastRtt());
701 BOOST_CHECK_EQUAL(face->srtt, group1_d.getSrtt());
702 BOOST_CHECK_EQUAL(face->face->getId(), 4);
703 face++;
704 //Group 2 - Unmeasured Faces
705 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
706 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
707 BOOST_CHECK_EQUAL(face->face->getId(), 5);
708 face++;
709 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
710 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
711 BOOST_CHECK_EQUAL(face->face->getId(), 6);
712 face++;
713 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
714 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
715 BOOST_CHECK_EQUAL(face->face->getId(), 7);
716 face++;
717 //Group 3 - Timeout
718 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
719 BOOST_CHECK_EQUAL(face->srtt, group3_a.getSrtt());
720 BOOST_CHECK_EQUAL(face->face->getId(), 8);
721 face++;
722 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
723 BOOST_CHECK_EQUAL(face->srtt, group3_b.getSrtt());
724 BOOST_CHECK_EQUAL(face->face->getId(), 9);
725 face++;
726 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
727 BOOST_CHECK_EQUAL(face->srtt, group3_c.getSrtt());
728 BOOST_CHECK_EQUAL(face->face->getId(), 10);
729 face++;
730 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
731 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
732 BOOST_CHECK_EQUAL(face->face->getId(), 11);
733 face++;
734 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
735 BOOST_CHECK_EQUAL(face->srtt, group3_e.getSrtt());
736 BOOST_CHECK_EQUAL(face->face->getId(), 12);
737 face++;
738 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
739 BOOST_CHECK_EQUAL(face->srtt, group3_f.getSrtt());
740 BOOST_CHECK_EQUAL(face->face->getId(), 13);
741 face++;
742 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
743 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
744 BOOST_CHECK_EQUAL(face->face->getId(), 14);
745 // face++;
746}
747
748BOOST_AUTO_TEST_CASE(FaceRankingForProbing)
749{
750 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
751 fw::asf::ProbingModule::FaceStatsProbingSet rankedFaces;
752
753 //Group 2- Unmeasured Faces
754 FaceInfo group2_a(nullptr);
755 DummyFace face2_a;
756 face2_a.setId(1);
757 rankedFaces.insert({&face2_a, FaceInfo::RTT_NO_MEASUREMENT,
758 FaceInfo::RTT_NO_MEASUREMENT, 0});
759 //Higher FaceId
760 FaceInfo group2_b(nullptr);
761 DummyFace face2_b;
762 face2_b.setId(2);
763 rankedFaces.insert({&face2_b, FaceInfo::RTT_NO_MEASUREMENT,
764 FaceInfo::RTT_NO_MEASUREMENT, 0});
765 //Higher Cost
766 FaceInfo group2_c(nullptr);
767 DummyFace face2_c;
768 face2_c.setId(3);
769 rankedFaces.insert({&face2_c, FaceInfo::RTT_NO_MEASUREMENT,
770 FaceInfo::RTT_NO_MEASUREMENT, 1});
771
772 //Group 1- Working Measured Faces
773 FaceInfo group1_a(nullptr);
774 group1_a.recordRtt(25_ms);
775 DummyFace face1_a;
776 face1_a.setId(4);
777 rankedFaces.insert({&face1_a, group1_a.getLastRtt(), group1_a.getSrtt(), 0});
778 // Higher FaceId
779 FaceInfo group1_b(nullptr);
780 group1_b.recordRtt(25_ms);
781 DummyFace face1_b;
782 face1_b.setId(5);
783 rankedFaces.insert({&face1_b, group1_b.getLastRtt(), group1_b.getSrtt(), 0});
784 //Higher SRTT
785 FaceInfo group1_c(nullptr);
786 group1_c.recordRtt(30_ms);
787 DummyFace face1_c;
788 face1_c.setId(6);
789 rankedFaces.insert({&face1_c, group1_c.getLastRtt(), group1_c.getSrtt(), 0});
790 //Higher SRTT/Cost
791 FaceInfo group1_d(nullptr);
792 group1_d.recordRtt(30_ms);
793 DummyFace face1_d;
794 face1_d.setId(7);
795 rankedFaces.insert({&face1_d, group1_d.getLastRtt(), group1_d.getSrtt(), 1});
796
797 //Group 3- Timeout Faces
798 //Lowest cost, high SRTT
799 FaceInfo group3_a(nullptr);
800 group3_a.recordRtt(30_ms);
801 group3_a.recordTimeout(PRODUCER_PREFIX);
802 DummyFace face3_a;
803 face3_a.setId(8);
804 rankedFaces.insert({&face3_a, group3_a.getLastRtt(), group3_a.getSrtt(), 0});
805 //Lowest cost, lower SRTT, higher FaceId
806 FaceInfo group3_b(nullptr);
807 group3_b.recordRtt(30_ms);
808 group3_b.recordTimeout(PRODUCER_PREFIX);
809 DummyFace face3_b;
810 face3_b.setId(9);
811 rankedFaces.insert({&face3_b, group3_b.getLastRtt(), group3_b.getSrtt(), 0});
812 //Lowest cost, higher SRTT, higher FaceId
813 FaceInfo group3_c(nullptr);
814 group3_c.recordRtt(45_ms);
815 group3_c.recordTimeout(PRODUCER_PREFIX);
816 DummyFace face3_c;
817 face3_c.setId(10);
818 rankedFaces.insert({&face3_c, group3_c.getLastRtt(), group3_c.getSrtt(), 0});
819 //Lowest cost, no SRTT, higher FaceId
820 FaceInfo group3_d(nullptr);
821 group3_d.recordTimeout(PRODUCER_PREFIX);
822 DummyFace face3_d;
823 face3_d.setId(11);
824 rankedFaces.insert({&face3_d, group3_d.getLastRtt(), FaceInfo::RTT_NO_MEASUREMENT, 0});
825 //Higher cost, lower SRTT, higher FaceId
826 FaceInfo group3_e(nullptr);
827 group3_e.recordRtt(15_ms);
828 group3_e.recordTimeout(PRODUCER_PREFIX);
829 DummyFace face3_e;
830 face3_e.setId(12);
831 rankedFaces.insert({&face3_e, group3_e.getLastRtt(), group3_e.getSrtt(), 1});
832 //Higher cost, higher SRTT, higher FaceId
833 FaceInfo group3_f(nullptr);
834 group3_f.recordRtt(45_ms);
835 group3_f.recordTimeout(PRODUCER_PREFIX);
836 DummyFace face3_f;
837 face3_f.setId(13);
838 rankedFaces.insert({&face3_f, group3_f.getLastRtt(), group3_f.getSrtt(), 1});
839 //Higher cost, no SRTT, higher FaceId
840 FaceInfo group3_g(nullptr);
841 group3_g.recordTimeout(PRODUCER_PREFIX);
842 DummyFace face3_g;
843 face3_g.setId(14);
844 rankedFaces.insert({&face3_g, group3_g.getLastRtt(),
845 FaceInfo::RTT_NO_MEASUREMENT, 1});
846 auto face = rankedFaces.begin();
847
848 //Group 2 - Unmeasured Faces
849 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
850 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
851 BOOST_CHECK_EQUAL(face->face->getId(), 1);
852 face++;
853 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
854 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
855 BOOST_CHECK_EQUAL(face->face->getId(), 2);
856 face++;
857 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_NO_MEASUREMENT);
858 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
859 BOOST_CHECK_EQUAL(face->face->getId(), 3);
860 face++;
861 //Group 1 - Working Measured Faces
862 BOOST_CHECK_EQUAL(face->rtt, group1_a.getLastRtt());
863 BOOST_CHECK_EQUAL(face->srtt, group1_a.getSrtt());
864 BOOST_CHECK_EQUAL(face->face->getId(), 4);
865 face++;
866 BOOST_CHECK_EQUAL(face->rtt, group1_b.getLastRtt());
867 BOOST_CHECK_EQUAL(face->srtt, group1_b.getSrtt());
868 BOOST_CHECK_EQUAL(face->face->getId(), 5);
869 face++;
870 BOOST_CHECK_EQUAL(face->rtt, group1_c.getLastRtt());
871 BOOST_CHECK_EQUAL(face->srtt, group1_c.getSrtt());
872 BOOST_CHECK_EQUAL(face->face->getId(), 6);
873 face++;
874 BOOST_CHECK_EQUAL(face->rtt, group1_d.getLastRtt());
875 BOOST_CHECK_EQUAL(face->srtt, group1_d.getSrtt());
876 BOOST_CHECK_EQUAL(face->face->getId(), 7);
877 face++;
878 //Group 3 - Timeout
879 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
880 BOOST_CHECK_EQUAL(face->srtt, group3_a.getSrtt());
881 BOOST_CHECK_EQUAL(face->face->getId(), 8);
882 face++;
883 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
884 BOOST_CHECK_EQUAL(face->srtt, group3_b.getSrtt());
885 BOOST_CHECK_EQUAL(face->face->getId(), 9);
886 face++;
887 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
888 BOOST_CHECK_EQUAL(face->srtt, group3_c.getSrtt());
889 BOOST_CHECK_EQUAL(face->face->getId(), 10);
890 face++;
891 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
892 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
893 BOOST_CHECK_EQUAL(face->face->getId(), 11);
894 face++;
895 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
896 BOOST_CHECK_EQUAL(face->srtt, group3_e.getSrtt());
897 BOOST_CHECK_EQUAL(face->face->getId(), 12);
898 face++;
899 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
900 BOOST_CHECK_EQUAL(face->srtt, group3_f.getSrtt());
901 BOOST_CHECK_EQUAL(face->face->getId(), 13);
902 face++;
903 BOOST_CHECK_EQUAL(face->rtt, FaceInfo::RTT_TIMEOUT);
904 BOOST_CHECK_EQUAL(face->srtt, FaceInfo::RTT_NO_MEASUREMENT);
905 BOOST_CHECK_EQUAL(face->face->getId(), 14);
906 // face++;
907}
908
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000909BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
910BOOST_AUTO_TEST_SUITE_END() // Fw
911
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400912} // namespace nfd::tests