blob: 14aa777dea352c50c4733e5923b17e0ee6e029f2 [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);
146 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 24);
147 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 6);
148
149 // If the link from nodeA to nodeB fails, ASF should start using the Face
150 // to nodeD again.
151 linkAB->fail();
152
153 runConsumer();
154
155 // Only 59 Data because the first Interest to nodeB after the failure should timeout
156 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 59);
157 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 30);
158 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 30);
159
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();
168
169 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 89);
170 BOOST_CHECK_GE(linkAB->getFace(nodeA).getCounters().nOutInterests, 50);
171 BOOST_CHECK_LE(linkAD->getFace(nodeA).getCounters().nOutInterests, 40);
172
173 // If both links fail, nodeA should forward to the next hop with the lowest cost
174 linkAB->fail();
175 linkAD->fail();
176
177 runConsumer();
178
179 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 89);
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200180 BOOST_CHECK_LE(linkAB->getFace(nodeA).getCounters().nOutInterests, 61); // FIXME #3830
181 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 59); // FIXME #3830
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000182}
183
184BOOST_FIXTURE_TEST_CASE(Nack, AsfGridFixture)
185{
186 // nodeB has a FIB entry to reach the producer, but nodeD does not
187 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
188
189 // The strategy should first try to send to nodeD. But since nodeD does not have a route for
190 // the producer's prefix, it should return a NO_ROUTE Nack. The strategy should then start using the Face to
191 // nodeB.
192 runConsumer();
193
194 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nInNacks, 1);
195 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 29);
196 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 29);
197
198 // nodeD should receive 2 Interests: one for the very first Interest and
199 // another from a probe
200 BOOST_CHECK_GE(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
201}
202
Saurab Dulala6dec222019-04-01 00:15:10 -0500203class AsfStrategyDelayedDataFixture : public AsfGridFixture
204{
205protected:
206 AsfStrategyDelayedDataFixture()
207 : AsfGridFixture(Name(AsfStrategy::getStrategyName()), 400_ms)
208 {
209 }
210};
211
212BOOST_FIXTURE_TEST_CASE(InterestForwarding, AsfStrategyDelayedDataFixture)
213{
214
215 Name name(PRODUCER_PREFIX);
216 name.appendTimestamp();
217 shared_ptr<Interest> interest = makeInterest(name, true);
218
219 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
220 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
221
222 // The first interest should go via link AD
223 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
224 this->advanceClocks(10_ms, 100_ms);
225 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 1);
226
227 // Second interest should go via link AB
228 interest->refreshNonce();
229 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
230 this->advanceClocks(10_ms, 100_ms);
231 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nOutInterests, 1);
232
233 // The third interest should again go via AD, since both the face from A is already used
234 // and so asf should choose the earliest used face i.e. AD
235 interest->refreshNonce();
236 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
237 this->advanceClocks(10_ms, 100_ms);
238 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests, 2);
239
240 this->advanceClocks(time::milliseconds(500), time::seconds(5));
241 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nInData, 1);
242 BOOST_CHECK_EQUAL(linkAB->getFace(nodeA).getCounters().nInData, 1);
243 BOOST_CHECK_EQUAL(consumer->getForwarderFace().getCounters().nOutData, 1);
244
245}
246
247BOOST_AUTO_TEST_CASE(Retransmission)
248{
249 // This is a unit test written to recreate the following issue
250 // https://redmine.named-data.net/issues/4874
251 /*
252 * +---------+ 10ms +---------+
253 * | nodeB | ------> | nodeC |
254 * +---------+ +---------+
255 */
256 // Avoid clearing pit entry for those incoming interest that have pit entry but no next hops
257
258 static const Name PRODUCER_PREFIX = "ndn:/pnr/C";
259 Name parameters = AsfStrategy::getStrategyName();
260 TopologyTester topo;
261
262 TopologyNode nodeB = topo.addForwarder("B"),
263 nodeC = topo.addForwarder("C");
264
265 topo.setStrategy<AsfStrategy>(nodeB, Name("ndn:/"), parameters);
266 topo.setStrategy<AsfStrategy>(nodeC, Name("ndn:/"), parameters);
267
268 shared_ptr<TopologyLink> linkBC = topo.addLink("BC", time::milliseconds(10), {nodeB, nodeC});
269
270 shared_ptr<TopologyAppLink> consumer = topo.addAppFace("c", nodeB),
271 producer = topo.addAppFace("p", nodeC, PRODUCER_PREFIX);
272
273 topo.addEchoProducer(producer->getClientFace(), PRODUCER_PREFIX, 100_ms);
274
275 Name name(PRODUCER_PREFIX);
276 name.appendTimestamp();
277 auto interest = makeInterest(name, true);
278
279 nfd::pit::Pit& pit = topo.getForwarder(nodeB).getPit();
280 shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
281
282 topo.getForwarder(nodeB).onOutgoingInterest(pitEntry, FaceEndpoint(linkBC->getFace(nodeB), 0), *interest);
283 this->advanceClocks(time::milliseconds(100));
284
285 interest->refreshNonce();
286 consumer->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
287 this->advanceClocks(time::milliseconds(100));
288
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000289 pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(linkBC->getFace(nodeB));
Saurab Dulala6dec222019-04-01 00:15:10 -0500290 BOOST_CHECK(outRecord != pitEntry->out_end());
291
292 this->advanceClocks(time::milliseconds(100));
293 BOOST_CHECK_EQUAL(linkBC->getFace(nodeC).getCounters().nOutData, 1);
294 BOOST_CHECK_EQUAL(linkBC->getFace(nodeB).getCounters().nInData, 1);
295}
296
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000297BOOST_AUTO_TEST_CASE(NoPitOutRecordAndProbeInterestNewNonce)
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600298{
299 /* +---------+
300 * | nodeD |
301 * +---------+
302 * |
303 * | 80ms
304 * |
305 * |
306 * +---------+
307 * +----->| nodeB |<------+
308 * | +---------+ |
309 * 15ms | | 16ms
310 * v v
311 * +---------+ +---------+
312 * | nodeA |--------------| nodeC |
313 * +---------+ 14ms +---------+
314 */
315
316 const Name PRODUCER_PREFIX = "/ndn/edu/nodeD/ping";
317
318 TopologyTester topo;
319 TopologyNode nodeA = topo.addForwarder("A"),
320 nodeB = topo.addForwarder("B"),
321 nodeC = topo.addForwarder("C"),
322 nodeD = topo.addForwarder("D");
323
324 for (TopologyNode node : {nodeA, nodeB, nodeC, nodeD}) {
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500325 topo.setStrategy<AsfStrategy>(node);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600326 }
327
Davide Pesavento14e71f02019-03-28 17:35:25 -0400328 shared_ptr<TopologyLink> linkAB = topo.addLink("AB", 15_ms, {nodeA, nodeB}),
329 linkAC = topo.addLink("AC", 14_ms, {nodeA, nodeC}),
330 linkBC = topo.addLink("BC", 16_ms, {nodeB, nodeC}),
331 linkBD = topo.addLink("BD", 80_ms, {nodeB, nodeD});
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600332
333 shared_ptr<TopologyAppLink> ping = topo.addAppFace("c", nodeA),
334 pingServer = topo.addAppFace("p", nodeD, PRODUCER_PREFIX);
335 topo.addEchoProducer(pingServer->getClientFace());
336
337 // Register prefixes
338 topo.registerPrefix(nodeA, linkAB->getFace(nodeA), PRODUCER_PREFIX, 15);
339 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 14);
340 topo.registerPrefix(nodeC, linkBC->getFace(nodeC), PRODUCER_PREFIX, 16);
341 topo.registerPrefix(nodeB, linkBD->getFace(nodeB), PRODUCER_PREFIX, 80);
342
343 // Send 6 interest since probes can be scheduled b/w 0-5 seconds
344 for (int i = 1; i < 7; i++) {
345 // Send ping number i
346 Name name(PRODUCER_PREFIX);
347 name.appendTimestamp();
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400348 auto interest = makeInterest(name);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600349 ping->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400350 auto nonce = interest->getNonce();
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600351
352 // Don't know when the probe will be triggered since it is random between 0-5 seconds
353 // or whether it will be triggered for this interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400354 for (int j = 1; j <= 1000 && linkAB->getFace(nodeA).getCounters().nOutInterests != 1; ++j) {
355 this->advanceClocks(1_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600356 }
357
358 // Check if probe is sent to B else send another ping
359 if (linkAB->getFace(nodeA).getCounters().nOutInterests == 1) {
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000360 // Get pitEntry of node A
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400361 auto pitEntry = topo.getForwarder(nodeA).getPit().find(*interest);
362 // Get outRecord associated with face towards B
363 auto outRecord = pitEntry->getOutRecord(linkAB->getFace(nodeA));
364 BOOST_REQUIRE(outRecord != pitEntry->out_end());
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000365
Davide Pesavento51cf75c2020-03-11 22:21:13 -0400366 // Check that Nonce of interest is not equal to Nonce of Probe
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000367 BOOST_CHECK_NE(nonce, outRecord->getLastNonce());
368
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600369 // B should not have received the probe interest yet
370 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 0);
371
372 // i-1 interests through B when no probe
373 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i - 1);
374
375 // After 15ms, B should get the probe interest
Davide Pesavento14e71f02019-03-28 17:35:25 -0400376 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600377 BOOST_CHECK_EQUAL(linkAB->getFace(nodeB).getCounters().nInInterests, 1);
378 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nOutInterests, i);
379
Ashlesh Gawande2a73f352016-12-01 15:37:03 +0000380 pitEntry = topo.getForwarder(nodeB).getPit().find(*interest);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600381
382 // Get outRecord associated with face towards D.
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000383 outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600384 BOOST_CHECK(outRecord != pitEntry->out_end());
385
386 // RTT between B and D
Davide Pesavento14e71f02019-03-28 17:35:25 -0400387 this->advanceClocks(5_ms, 160_ms);
Md Ashiqur Rahmanc88d2d42019-08-28 20:19:47 +0000388 outRecord = pitEntry->getOutRecord(linkBD->getFace(nodeB));
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600389
390 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i);
391
392 BOOST_CHECK(outRecord == pitEntry->out_end());
393
394 // Data is returned for the ping after 15 ms - will result in false measurement
395 // 14+16-15 = 15ms
396 // Since outRecord == pitEntry->out_end()
Davide Pesavento14e71f02019-03-28 17:35:25 -0400397 this->advanceClocks(1_ms, 15_ms);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600398 BOOST_CHECK_EQUAL(linkBD->getFace(nodeB).getCounters().nInData, i+1);
399
400 break;
401 }
402 }
403}
404
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500405BOOST_FIXTURE_TEST_CASE(IgnoreTimeouts, AsfStrategyParametersGridFixture)
406{
407 // Both nodeB and nodeD have FIB entries to reach the producer
408 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
409 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
410
411 // Send 15 interests let it change to use the 10 ms link
412 runConsumer(15);
413
414 int outInterestsBeforeFailure = linkAD->getFace(nodeA).getCounters().nOutInterests;
415
416 // Bring down 10 ms link
417 linkAB->fail();
418
419 // Send 6 interests, first 5 will be ignored and on the 6th it will record the timeout
420 // ready to switch for the next interest
421 runConsumer(6);
422
423 // Check that link has not been switched to 100 ms because n-silent-timeouts = 5
424 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests - outInterestsBeforeFailure, 0);
425
426 // Send 5 interests, check that 100 ms link is used
427 runConsumer(5);
428
429 BOOST_CHECK_EQUAL(linkAD->getFace(nodeA).getCounters().nOutInterests - outInterestsBeforeFailure, 5);
430}
431
432BOOST_FIXTURE_TEST_CASE(ProbingInterval, AsfStrategyParametersGridFixture)
433{
434 // Both nodeB and nodeD have FIB entries to reach the producer
435 topo.registerPrefix(nodeB, linkBC->getFace(nodeB), PRODUCER_PREFIX);
436 topo.registerPrefix(nodeD, linkCD->getFace(nodeD), PRODUCER_PREFIX);
437
438 // Send 6 interests let it change to use the 10 ms link
439 runConsumer(6);
440
Davide Pesavento14e71f02019-03-28 17:35:25 -0400441 shared_ptr<TopologyLink> linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeD});
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500442 topo.registerPrefix(nodeA, linkAC->getFace(nodeA), PRODUCER_PREFIX, 1);
443
444 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 0);
445
446 // After 30 seconds a probe would be sent that would switch make ASF switch
447 runConsumer(30);
448
449 BOOST_CHECK_EQUAL(linkAC->getFace(nodeA).getCounters().nOutInterests, 1);
450}
451
452class ParametersFixture
453{
454public:
455 void
456 checkValidity(std::string parameters, bool isCorrect)
457 {
458 Name strategyName(Name(AsfStrategy::getStrategyName()).append(parameters));
459 if (isCorrect) {
460 BOOST_CHECK_NO_THROW(make_unique<AsfStrategy>(forwarder, strategyName));
461 }
462 else {
463 BOOST_CHECK_THROW(make_unique<AsfStrategy>(forwarder, strategyName), std::invalid_argument);
464 }
465 }
466
467protected:
Davide Pesaventoa4abfb02019-10-06 16:02:56 -0400468 FaceTable faceTable;
469 Forwarder forwarder{faceTable};
Ashlesh Gawande92e4ea52017-07-19 11:38:12 -0500470};
471
472BOOST_FIXTURE_TEST_CASE(InstantiationTest, ParametersFixture)
473{
474 checkValidity("/probing-interval~30000/n-silent-timeouts~5", true);
475 checkValidity("/n-silent-timeouts~5/probing-interval~30000", true);
476 checkValidity("/probing-interval~30000", true);
477 checkValidity("/n-silent-timeouts~5", true);
478 checkValidity("", true);
479
480 checkValidity("/probing-interval~500", false); // At least 1 seconds
481 checkValidity("/probing-interval~-5000", false);
482 checkValidity("/n-silent-timeouts~-5", false);
483 checkValidity("/n-silent-timeouts~-5/probing-interval~-30000", false);
484 checkValidity("/n-silent-timeouts", false);
485 checkValidity("/probing-interval~", false);
486 checkValidity("/~1000", false);
487 checkValidity("/probing-interval~foo", false);
488 checkValidity("/n-silent-timeouts~1~2", false);
489}
490
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000491BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
492BOOST_AUTO_TEST_SUITE_END() // Fw
493
494} // namespace tests
495} // namespace asf
496} // namespace fw
497} // namespace nfd