blob: 90e8524c43dab4103595d09ccedcc6604b578ae9 [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/*
Davide Pesavento51cf75c2020-03-11 22:21:13 -04003 * Copyright (c) 2014-2020, 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
Junxiao Shi890afe92016-12-15 14:34:34 +000028#include "strategy-tester.hpp"
Vince Lehman8a4c29e2016-07-11 08:49:35 +000029#include "topology-tester.hpp"
30
31namespace nfd {
32namespace fw {
33namespace asf {
34namespace tests {
35
36using namespace nfd::fw::tests;
37
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 Dulala6dec222019-04-01 00:15:10 -050049 AsfGridFixture(const Name& params = AsfStrategy::getStrategyName(), time::nanoseconds replyDelay = 0_ms)
Davide Pesavento14e71f02019-03-28 17:35:25 -040050 : parameters(params)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000051 {
52 /*
53 * +---------+
54 * +----->| nodeB |<------+
55 * | +---------+ |
56 * 10ms | | 10ms
57 * v v
58 * +---------+ +---------+
59 * | nodeA | | nodeC |
60 * +---------+ +---------+
61 * ^ ^
62 * 100ms | | 100ms
63 * | +---------+ |
64 * +----->| nodeD |<------+
65 * +---------+
66 */
67
68 nodeA = topo.addForwarder("A");
69 nodeB = topo.addForwarder("B");
70 nodeC = topo.addForwarder("C");
71 nodeD = topo.addForwarder("D");
72
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -050073 topo.setStrategy<AsfStrategy>(nodeA, Name("ndn:/"), parameters);
74 topo.setStrategy<AsfStrategy>(nodeB, Name("ndn:/"), parameters);
75 topo.setStrategy<AsfStrategy>(nodeC, Name("ndn:/"), parameters);
76 topo.setStrategy<AsfStrategy>(nodeD, Name("ndn:/"), parameters);
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
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -050094 runConsumer(int 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
117 static const Name PRODUCER_PREFIX;
118};
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")
126 .append("n-silent-timeouts~5"))
127 {
128 }
129};
130
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000131const Name AsfGridFixture::PRODUCER_PREFIX = Name("ndn:/hr/C");
132
133BOOST_FIXTURE_TEST_CASE(Basic, AsfGridFixture)
134{
135 // Both nodeB and nodeD have FIB entries to reach the producer
136 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
137 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
138
139 runConsumer();
140
141 // ASF should use the Face to nodeD because it has lower routing cost.
142 // After 5 seconds, a probe Interest should be sent to the Face to nodeB,
143 // and the probe should return Data quicker. ASF should then use the Face
144 // to nodeB to forward the remaining Interests.
145 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 30);
Alex Lane9cec6992020-03-05 19:10:09 -0600146 // Because of exploration, will forward to AB and AD simultaneously at least once
147 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 25);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000148 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 6);
149
150 // If the link from nodeA to nodeB fails, ASF should start using the Face
151 // to nodeD again.
152 linkAB->fail();
153
154 runConsumer();
Alex Lane9cec6992020-03-05 19:10:09 -0600155 // We experience 3 silent timeouts before marking AB as timed out on the fourth interest.
156 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 56);
157 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 36);
158 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 24);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000159
160 // If the link from nodeA to nodeB recovers, ASF should probe the Face
161 // to nodeB and start using it again.
162 linkAB->recover();
163
164 // Advance time to ensure probing is due
Davide Pesavento14e71f02019-03-28 17:35:25 -0400165 this->advanceClocks(10_ms, 10_s);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000166
167 runConsumer();
Alex Lane9cec6992020-03-05 19:10:09 -0600168 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 86);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000169 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 50);
170 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 40);
171
172 // If both links fail, nodeA should forward to the next hop with the lowest cost
173 linkAB->fail();
174 linkAD->fail();
175
176 runConsumer();
177
Alex Lane9cec6992020-03-05 19:10:09 -0600178 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 86);
179 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 65); // FIXME #3830
180 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 57); // FIXME #3830
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000181}
182
183BOOST_FIXTURE_TEST_CASE(Nack, AsfGridFixture)
184{
185 // nodeB has a FIB entry to reach the producer, but nodeD does not
186 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
187
188 // The strategy should first try to send to nodeD. But since nodeD does not have a route for
189 // the producer's prefix, it should return a NO_ROUTE Nack. The strategy should then start using the Face to
190 // nodeB.
191 runConsumer();
192
193 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nInNacks, 1);
194 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 29);
195 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 29);
196
197 // nodeD should receive 2 Interests: one for the very first Interest and
198 // another from a probe
199 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
200}
201
Saurab Dulala6dec222019-04-01 00:15:10 -0500202class AsfStrategyDelayedDataFixture : public AsfGridFixture
203{
204protected:
205 AsfStrategyDelayedDataFixture()
206 : AsfGridFixture(Name(AsfStrategy::getStrategyName()), 400_ms)
207 {
208 }
209};
210
211BOOST_FIXTURE_TEST_CASE(InterestForwarding, AsfStrategyDelayedDataFixture)
212{
213
214 Name name(PRODUCER_PREFIX);
215 name.appendTimestamp();
216 shared_ptr<Interest> interest = makeInterest(name, true);
217
218 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
219 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
220
221 // The first interest should go via link AD
222 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
223 this->advanceClocks(10_ms, 100_ms);
224 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 1);
225
226 // Second interest should go via link AB
227 interest->refreshNonce();
228 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
229 this->advanceClocks(10_ms, 100_ms);
230 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 1);
231
232 // The third interest should again go via AD, since both the face from A is already used
233 // and so asf should choose the earliest used face i.e. AD
234 interest->refreshNonce();
235 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
236 this->advanceClocks(10_ms, 100_ms);
237 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
238
239 this->advanceClocks(time::milliseconds(500), time::seconds(5));
240 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nInData, 1);
241 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 1);
242 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 1);
243
244}
245
246BOOST_AUTO_TEST_CASE(Retransmission)
247{
248 // This is a unit test written to recreate the following issue
249 // https://redmine.named-data.net/issues/4874
250 /*
251 * +---------+ 10ms +---------+
252 * | nodeB | ------> | nodeC |
253 * +---------+ +---------+
254 */
255 // Avoid clearing pit entry for those incoming interest that have pit entry but no next hops
256
257 static const Name PRODUCER_PREFIX = "ndn:/pnr/C";
258 Name parameters = AsfStrategy::getStrategyName();
259 TopologyTester topo;
260
261 TopologyNode nodeB = topo.addForwarder("B"),
262 nodeC = topo.addForwarder("C");
263
264 topo.setStrategy<AsfStrategy>(nodeB, Name("ndn:/"), parameters);
265 topo.setStrategy<AsfStrategy>(nodeC, Name("ndn:/"), parameters);
266
267 shared_ptr<TopologyLink> linkBC = topo.addLink("BC", time::milliseconds(10), {nodeB, nodeC});
268
269 shared_ptr<TopologyAppLink> consumer = topo.addAppFace("c", nodeB),
270 producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
271
272 topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, 100_ms);
273
274 Name name(PRODUCER_PREFIX);
275 name.appendTimestamp();
276 auto interest = makeInterest(name, true);
277
278 nfd::pit::Pit& pit = topo.getForwarder(nodeB).getPit();
279 shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
280
281 topo.getForwarder(nodeB).onOutgoingInterest(pitEntry, FaceEndpoint(linkBC->getFace(nodeB), 0), *interest);
282 this->advanceClocks(time::milliseconds(100));
283
284 interest->refreshNonce();
285 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
286 this->advanceClocks(time::milliseconds(100));
287
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000288 pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(linkBC->getFace(nodeB));
Saurab Dulala6dec222019-04-01 00:15:10 -0500289 BOOST_CHECK(outRecord != pitEntry->out_end());
290
291 this->advanceClocks(time::milliseconds(100));
292 BOOST_CHECK_EQUAL(linkBC->getFace(nodeC).getCounters().nOutData, 1);
293 BOOST_CHECK_EQUAL(linkBC->getFace(nodeB).getCounters().nInData, 1);
294}
295
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000296BOOST_AUTO_TEST_CASE(NoPitOutRecordAndProbeInterestNewNonce)
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600297{
298 /* +---------+
299 * | nodeD |
300 * +---------+
301 * |
302 * | 80ms
303 * |
304 * |
305 * +---------+
306 * +----->| nodeB |<------+
307 * | +---------+ |
308 * 15ms | | 16ms
309 * v v
310 * +---------+ +---------+
311 * | nodeA |--------------| nodeC |
312 * +---------+ 14ms +---------+
313 */
314
315 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
316
317 TopologyTester topo;
318 TopologyNode nodeA = topo.addForwarder("A"),
319 nodeB = topo.addForwarder("B"),
320 nodeC = topo.addForwarder("C"),
321 nodeD = topo.addForwarder("D");
322
323 for (TopologyNode node : {nodeA, nodeB, nodeC, nodeD}) {
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500324 topo.setStrategy<AsfStrategy>(node);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600325 }
326
Davide Pesavento14e71f02019-03-28 17:35:25 -0400327 shared_ptr<TopologyLink> linkAB = topo.addLink("AB", 15_ms, {nodeA, nodeB}),
328 linkAC = topo.addLink("AC", 14_ms, {nodeA, nodeC}),
329 linkBC = topo.addLink("BC", 16_ms, {nodeB, nodeC}),
330 linkBD = topo.addLink("BD", 80_ms, {nodeB, nodeD});
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600331
332 shared_ptr<TopologyAppLink> ping = topo.addAppFace("c", nodeA),
333 pingServer = topo.addAppFace("p", nodeD, PRODUCER_PREFIX);
334 topo.addEchoProducer(pingServer->getClientFace());
335
336 // Register prefixes
337 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 15);
338 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 14);
339 topo.registerPrefix(nodeC, linkBC->getFace(nodeC), PRODUCER_PREFIX, 16);
340 topo.registerPrefix(nodeB, linkBD->getFace(nodeB), PRODUCER_PREFIX, 80);
341
342 // Send 6 interest since probes can be scheduled b/w 0-5 seconds
343 for (int i = 1; i < 7; i++) {
344 // Send ping number i
345 Name name(PRODUCER_PREFIX);
346 name.appendTimestamp();
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400347 auto interest = makeInterest(name);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600348 ping->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400349 auto nonce = interest->getNonce();
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600350
351 // Don't know when the probe will be triggered since it is random between 0-5 seconds
352 // or whether it will be triggered for this interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400353 for (int j = 1; j <= 1000 && linkAB->getFace(nodeA).getCounters().nOutInterests != 1; ++j) {
354 this->advanceClocks(1_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600355 }
356
357 // Check if probe is sent to B else send another ping
358 if (linkAB->getFace(nodeA).getCounters().nOutInterests == 1) {
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000359 // Get pitEntry of node A
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400360 auto pitEntry = topo.getForwarder(nodeA).getPit().find(*interest);
361 // Get outRecord associated with face towards B
362 auto outRecord = pitEntry->getOutRecord(linkAB->getFace(nodeA));
363 BOOST_REQUIRE(outRecord != pitEntry->out_end());
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000364
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400365 // Check that Nonce of interest is not equal to Nonce of Probe
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000366 BOOST_CHECK_NE(nonce, outRecord->getLastNonce());
367
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600368 // B should not have received the probe interest yet
369 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 0);
370
371 // i-1 interests through B when no probe
372 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i - 1);
373
374 // After 15ms, B should get the probe interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400375 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600376 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 1);
377 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i);
378
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000379 pitEntry = topo.getForwarder(nodeB).getPit().find(*interest);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600380
381 // Get outRecord associated with face towards D.
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000382 outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600383 BOOST_CHECK(outRecord != pitEntry->out_end());
384
385 // RTT between B and D
Davide Pesavento14e71f02019-03-28 17:35:25 -0400386 this->advanceClocks(5_ms, 160_ms);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000387 outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600388
389 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i);
390
391 BOOST_CHECK(outRecord == pitEntry->out_end());
392
393 // Data is returned for the ping after 15 ms - will result in false measurement
394 // 14+16-15 = 15ms
395 // Since outRecord == pitEntry->out_end()
Davide Pesavento14e71f02019-03-28 17:35:25 -0400396 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600397 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i+1);
398
399 break;
400 }
401 }
402}
403
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500404BOOST_FIXTURE_TEST_CASE(IgnoreTimeouts, AsfStrategyParametersGridFixture)
405{
406 // Both nodeB and nodeD have FIB entries to reach the producer
407 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
408 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
409
410 // Send 15 interests let it change to use the 10 ms link
411 runConsumer(15);
412
413 int outInterestsBeforeFailure = linkAD->getFace(nodeA).getCounters().nOutInterests;
414
415 // Bring down 10 ms link
416 linkAB->fail();
417
418 // Send 6 interests, first 5 will be ignored and on the 6th it will record the timeout
419 // ready to switch for the next interest
420 runConsumer(6);
421
422 // Check that link has not been switched to 100 ms because n-silent-timeouts = 5
423 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests - outInterestsBeforeFailure, 0);
424
425 // Send 5 interests, check that 100 ms link is used
426 runConsumer(5);
427
428 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests - outInterestsBeforeFailure, 5);
429}
430
431BOOST_FIXTURE_TEST_CASE(ProbingInterval, AsfStrategyParametersGridFixture)
432{
433 // Both nodeB and nodeD have FIB entries to reach the producer
434 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
435 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
436
437 // Send 6 interests let it change to use the 10 ms link
438 runConsumer(6);
439
Davide Pesavento14e71f02019-03-28 17:35:25 -0400440 shared_ptr<TopologyLink> linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeD});
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500441 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 1);
442
443 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 0);
444
445 // After 30 seconds a probe would be sent that would switch make ASF switch
446 runConsumer(30);
447
448 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 1);
449}
450
451class ParametersFixture
452{
453public:
454 void
455 checkValidity(std::string parameters, bool isCorrect)
456 {
457 Name strategyName(Name(AsfStrategy::getStrategyName()).append(parameters));
458 if (isCorrect) {
459 BOOST_CHECK_NO_THROW(make_unique<AsfStrategy>(forwarder, strategyName));
460 }
461 else {
462 BOOST_CHECK_THROW(make_unique<AsfStrategy>(forwarder, strategyName), std::invalid_argument);
463 }
464 }
465
466protected:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400467 FaceTable faceTable;
468 Forwarder forwarder{faceTable};
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500469};
470
471BOOST_FIXTURE_TEST_CASE(InstantiationTest, ParametersFixture)
472{
473 checkValidity("/probing-interval~30000/n-silent-timeouts~5", true);
474 checkValidity("/n-silent-timeouts~5/probing-interval~30000", true);
475 checkValidity("/probing-interval~30000", true);
476 checkValidity("/n-silent-timeouts~5", true);
477 checkValidity("", true);
478
479 checkValidity("/probing-interval~500", false); // At least 1 seconds
480 checkValidity("/probing-interval~-5000", false);
481 checkValidity("/n-silent-timeouts~-5", false);
482 checkValidity("/n-silent-timeouts~-5/probing-interval~-30000", false);
483 checkValidity("/n-silent-timeouts", false);
484 checkValidity("/probing-interval~", false);
485 checkValidity("/~1000", false);
486 checkValidity("/probing-interval~foo", false);
487 checkValidity("/n-silent-timeouts~1~2", false);
488}
489
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000490BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
491BOOST_AUTO_TEST_SUITE_END() // Fw
492
493} // namespace tests
494} // namespace asf
495} // namespace fw
496} // namespace nfd