blob: 629f93350bbca9d69a46727cb3dc7c337eb540a1 [file] [log] [blame]
Vince Lehman942eb7b2014-10-02 10:09:27 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
dmcoomescf8d0ed2017-02-21 11:39:01 -06003 * Copyright (c) 2014-2018, The University of Memphis,
Nick Gordonf8b5bcd2016-08-11 15:06:50 -05004 * Regents of the University of California
Vince Lehman942eb7b2014-10-02 10:09:27 -05005 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
19 *
20 **/
21
Nick Gordon5867b522017-09-06 17:41:37 -050022#include "route/fib.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050023#include "test-common.hpp"
24#include "control-commands.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050025#include "adjacency-list.hpp"
26#include "conf-parameter.hpp"
27
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060028#include <ndn-cxx/util/dummy-client-face.hpp>
29
Vince Lehman942eb7b2014-10-02 10:09:27 -050030namespace nlsr {
31namespace test {
32
dmcoomes9f936662017-03-02 10:33:09 -060033using std::shared_ptr;
Vince Lehman942eb7b2014-10-02 10:09:27 -050034
Muktadir Chowdhury3be64662015-05-01 14:50:53 -050035class FibFixture : public UnitTestTimeFixture
Vince Lehman942eb7b2014-10-02 10:09:27 -050036{
37public:
38 FibFixture()
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050039 : face(std::make_shared<ndn::util::DummyClientFace>(m_keyChain))
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060040 , interests(face->sentInterests)
Vince Lehman942eb7b2014-10-02 10:09:27 -050041 {
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050042 Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050043 adjacencies.insert(neighbor1);
44
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050045 Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050046 adjacencies.insert(neighbor2);
47
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050048 Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050049 adjacencies.insert(neighbor3);
50
51 conf.setMaxFacesPerPrefix(2);
52
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050053 fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
Vince Lehman942eb7b2014-10-02 10:09:27 -050054
55 fib->m_faceMap.update(router1FaceUri, router1FaceId);
56 fib->m_faceMap.update(router2FaceUri, router2FaceId);
57 fib->m_faceMap.update(router3FaceUri, router3FaceId);
58 }
59
60public:
dmcoomes9f936662017-03-02 10:33:09 -060061 std::shared_ptr<ndn::util::DummyClientFace> face;
dmcoomes9f936662017-03-02 10:33:09 -060062 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050063
64 AdjacencyList adjacencies;
65 ConfParameter conf;
66 std::vector<ndn::Interest>& interests;
67
68 static const ndn::Name router1Name;
69 static const ndn::Name router2Name;
70 static const ndn::Name router3Name;
71
72 static const std::string router1FaceUri;
73 static const std::string router2FaceUri;
74 static const std::string router3FaceUri;
75
76 static const uint32_t router1FaceId;
77 static const uint32_t router2FaceId;
78 static const uint32_t router3FaceId;
79};
80
81const ndn::Name FibFixture::router1Name = "/ndn/router1";
82const ndn::Name FibFixture::router2Name = "/ndn/router2";
83const ndn::Name FibFixture::router3Name = "/ndn/router3";
84
Nick Gordone9733ed2017-04-26 10:48:39 -050085const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
86const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
87const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050088
89const uint32_t FibFixture::router1FaceId = 1;
90const uint32_t FibFixture::router2FaceId = 2;
91const uint32_t FibFixture::router3FaceId = 3;
92
93BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
94
95BOOST_AUTO_TEST_CASE(NextHopsAdd)
96{
97 NextHop hop1(router1FaceUri, 10);
98 NextHop hop2(router2FaceUri, 20);
99
100 NexthopList hops;
101 hops.addNextHop(hop1);
102 hops.addNextHop(hop2);
103
Nick Gordon5867b522017-09-06 17:41:37 -0500104 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500105 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500106
107 // Should register faces 1 and 2 for /ndn/name
108 BOOST_REQUIRE_EQUAL(interests.size(), 2);
109
110 ndn::nfd::ControlParameters extractedParameters;
111 ndn::Name::Component verb;
112 std::vector<ndn::Interest>::iterator it = interests.begin();
113
114 extractRibCommandParameters(*it, verb, extractedParameters);
115
116 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
117 extractedParameters.getFaceId() == router1FaceId &&
118 verb == ndn::Name::Component("register"));
119
120 ++it;
121 extractRibCommandParameters(*it, verb, extractedParameters);
122
123 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
124 extractedParameters.getFaceId() == router2FaceId &&
125 verb == ndn::Name::Component("register"));
126}
127
128
129BOOST_AUTO_TEST_CASE(NextHopsNoChange)
130{
131 NextHop hop1(router1FaceUri, 10);
132 NextHop hop2(router2FaceUri, 20);
133
134 NexthopList oldHops;
135 oldHops.addNextHop(hop1);
136 oldHops.addNextHop(hop2);
137
Nick Gordon5867b522017-09-06 17:41:37 -0500138 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500139 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500140
141 BOOST_REQUIRE_EQUAL(interests.size(), 2);
142 interests.clear();
143
Nick Gordon5867b522017-09-06 17:41:37 -0500144 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500145 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500146
147 // Should register face 1 and 2 for /ndn/name
148 BOOST_REQUIRE_EQUAL(interests.size(), 2);
149
150 ndn::nfd::ControlParameters extractedParameters;
151 ndn::Name::Component verb;
152 std::vector<ndn::Interest>::iterator it = interests.begin();
153
154 extractRibCommandParameters(*it, verb, extractedParameters);
155
156 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
157 extractedParameters.getFaceId() == router1FaceId &&
158 verb == ndn::Name::Component("register"));
159
160 ++it;
161 extractRibCommandParameters(*it, verb, extractedParameters);
162
163 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
164 extractedParameters.getFaceId() == router2FaceId &&
165 verb == ndn::Name::Component("register"));
166}
167
168BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
169{
170 NextHop hop1(router1FaceUri, 10);
171 NextHop hop2(router2FaceUri, 20);
172
173 NexthopList oldHops;
174 oldHops.addNextHop(hop1);
175 oldHops.addNextHop(hop2);
176
Nick Gordon5867b522017-09-06 17:41:37 -0500177 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500178 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500179
180 BOOST_REQUIRE_EQUAL(interests.size(), 2);
181 interests.clear();
182
183 NexthopList empty;
184
Nick Gordon5867b522017-09-06 17:41:37 -0500185 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500186 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500187
188 // Should unregister faces 1 and 2 for /ndn/name
189 BOOST_CHECK_EQUAL(interests.size(), 2);
190
191 ndn::nfd::ControlParameters extractedParameters;
192 ndn::Name::Component verb;
193 std::vector<ndn::Interest>::iterator it = interests.begin();
194
195 extractRibCommandParameters(*it, verb, extractedParameters);
196
197 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
198 extractedParameters.getFaceId() == router1FaceId &&
199 verb == ndn::Name::Component("unregister"));
200
201 ++it;
202 extractRibCommandParameters(*it, verb, extractedParameters);
203
204 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
205 extractedParameters.getFaceId() == router2FaceId &&
206 verb == ndn::Name::Component("unregister"));
207}
208
209BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
210{
211 NextHop hop1(router1FaceUri, 10);
212 NextHop hop2(router2FaceUri, 20);
213 NextHop hop3(router3FaceUri, 30);
214
215 NexthopList hops;
216 hops.addNextHop(hop1);
217 hops.addNextHop(hop2);
218 hops.addNextHop(hop3);
219
Nick Gordon5867b522017-09-06 17:41:37 -0500220 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500221 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500222
223 // Should only register faces 1 and 2 for /ndn/name
224 BOOST_CHECK_EQUAL(interests.size(), 2);
225
226 ndn::nfd::ControlParameters extractedParameters;
227 ndn::Name::Component verb;
228 std::vector<ndn::Interest>::iterator it = interests.begin();
229
230 extractRibCommandParameters(*it, verb, extractedParameters);
231
232 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
233 extractedParameters.getFaceId() == router1FaceId &&
234 verb == ndn::Name::Component("register"));
235
236 ++it;
237 extractRibCommandParameters(*it, verb, extractedParameters);
238
239 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
240 extractedParameters.getFaceId() == router2FaceId &&
241 verb == ndn::Name::Component("register"));
242}
243
244BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
245{
246 NextHop hop1(router1FaceUri, 10);
247 NextHop hop2(router2FaceUri, 20);
248
249 NexthopList hops;
250 hops.addNextHop(hop1);
251 hops.addNextHop(hop2);
252
Nick Gordon5867b522017-09-06 17:41:37 -0500253 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500254 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500255
256 // FIB
257 // Name NextHops
258 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
259 BOOST_REQUIRE_EQUAL(interests.size(), 2);
260 interests.clear();
261
262 // Routing table is recalculated; a new more optimal path is found
263 NextHop hop3(router3FaceUri, 5);
264 hops.addNextHop(hop3);
265
Nick Gordon5867b522017-09-06 17:41:37 -0500266 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500267 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500268
269 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
270 // unregistered. Face 1 will also be re-registered.
271 //
272 // FIB
273 // Name NextHops
274 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
275
276 BOOST_CHECK_EQUAL(interests.size(), 3);
277
278 ndn::nfd::ControlParameters extractedParameters;
279 ndn::Name::Component verb;
280 std::vector<ndn::Interest>::iterator it = interests.begin();
281
282 extractRibCommandParameters(*it, verb, extractedParameters);
283
284 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
285 extractedParameters.getFaceId() == router3FaceId &&
286 verb == ndn::Name::Component("register"));
287
288 ++it;
289 extractRibCommandParameters(*it, verb, extractedParameters);
290
291 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
292 extractedParameters.getFaceId() == router1FaceId &&
293 verb == ndn::Name::Component("register"));
294
295 ++it;
296 extractRibCommandParameters(*it, verb, extractedParameters);
297
298 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
299 extractedParameters.getFaceId() == router2FaceId &&
300 verb == ndn::Name::Component("unregister"));
301}
302
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500303BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
304{
305 ndn::Name name1("/name/1");
306 FibEntry fe(name1);
307 fib->m_table.emplace(name1, fe);
308 int origSeqNo = fe.getSeqNo();
309
310 fib->scheduleEntryRefresh(fe,
Ashlesh Gawandee6ba9152018-03-30 01:15:00 -0500311 [&] (FibEntry& entry) {
312 BOOST_CHECK_EQUAL(origSeqNo + 1, entry.getSeqNo());
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500313 });
314 this->advanceClocks(ndn::time::milliseconds(10), 1);
315}
316
Vince Lehman942eb7b2014-10-02 10:09:27 -0500317BOOST_AUTO_TEST_SUITE_END()
318
Nick Gordonfad8e252016-08-11 14:21:38 -0500319} // namespace test
320} // namespace nlsr