blob: 80408ebe0619aa419e73577374749be3e21df201 [file] [log] [blame]
Vince Lehman942eb7b2014-10-02 10:09:27 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, 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 {
42 INIT_LOGGERS("/tmp", "DEBUG");
43
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050044 Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050045 adjacencies.insert(neighbor1);
46
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050047 Adjacent neighbor2(router2Name, ndn::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050048 adjacencies.insert(neighbor2);
49
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050050 Adjacent neighbor3(router3Name, ndn::FaceUri(router3FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050051 adjacencies.insert(neighbor3);
52
53 conf.setMaxFacesPerPrefix(2);
54
Muktadir Chowdhuryf04f9892017-08-20 20:42:56 -050055 fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
Vince Lehman942eb7b2014-10-02 10:09:27 -050056
57 fib->m_faceMap.update(router1FaceUri, router1FaceId);
58 fib->m_faceMap.update(router2FaceUri, router2FaceId);
59 fib->m_faceMap.update(router3FaceUri, router3FaceId);
60 }
61
62public:
dmcoomes9f936662017-03-02 10:33:09 -060063 std::shared_ptr<ndn::util::DummyClientFace> face;
dmcoomes9f936662017-03-02 10:33:09 -060064 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050065
66 AdjacencyList adjacencies;
67 ConfParameter conf;
68 std::vector<ndn::Interest>& interests;
69
70 static const ndn::Name router1Name;
71 static const ndn::Name router2Name;
72 static const ndn::Name router3Name;
73
74 static const std::string router1FaceUri;
75 static const std::string router2FaceUri;
76 static const std::string router3FaceUri;
77
78 static const uint32_t router1FaceId;
79 static const uint32_t router2FaceId;
80 static const uint32_t router3FaceId;
81};
82
83const ndn::Name FibFixture::router1Name = "/ndn/router1";
84const ndn::Name FibFixture::router2Name = "/ndn/router2";
85const ndn::Name FibFixture::router3Name = "/ndn/router3";
86
Nick Gordone9733ed2017-04-26 10:48:39 -050087const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
88const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
89const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050090
91const uint32_t FibFixture::router1FaceId = 1;
92const uint32_t FibFixture::router2FaceId = 2;
93const uint32_t FibFixture::router3FaceId = 3;
94
95BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
96
97BOOST_AUTO_TEST_CASE(NextHopsAdd)
98{
99 NextHop hop1(router1FaceUri, 10);
100 NextHop hop2(router2FaceUri, 20);
101
102 NexthopList hops;
103 hops.addNextHop(hop1);
104 hops.addNextHop(hop2);
105
Nick Gordon5867b522017-09-06 17:41:37 -0500106 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500107 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500108
109 // Should register faces 1 and 2 for /ndn/name
110 BOOST_REQUIRE_EQUAL(interests.size(), 2);
111
112 ndn::nfd::ControlParameters extractedParameters;
113 ndn::Name::Component verb;
114 std::vector<ndn::Interest>::iterator it = interests.begin();
115
116 extractRibCommandParameters(*it, verb, extractedParameters);
117
118 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
119 extractedParameters.getFaceId() == router1FaceId &&
120 verb == ndn::Name::Component("register"));
121
122 ++it;
123 extractRibCommandParameters(*it, verb, extractedParameters);
124
125 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
126 extractedParameters.getFaceId() == router2FaceId &&
127 verb == ndn::Name::Component("register"));
128}
129
130
131BOOST_AUTO_TEST_CASE(NextHopsNoChange)
132{
133 NextHop hop1(router1FaceUri, 10);
134 NextHop hop2(router2FaceUri, 20);
135
136 NexthopList oldHops;
137 oldHops.addNextHop(hop1);
138 oldHops.addNextHop(hop2);
139
Nick Gordon5867b522017-09-06 17:41:37 -0500140 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500141 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500142
143 BOOST_REQUIRE_EQUAL(interests.size(), 2);
144 interests.clear();
145
Nick Gordon5867b522017-09-06 17:41:37 -0500146 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500147 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500148
149 // Should register face 1 and 2 for /ndn/name
150 BOOST_REQUIRE_EQUAL(interests.size(), 2);
151
152 ndn::nfd::ControlParameters extractedParameters;
153 ndn::Name::Component verb;
154 std::vector<ndn::Interest>::iterator it = interests.begin();
155
156 extractRibCommandParameters(*it, verb, extractedParameters);
157
158 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
159 extractedParameters.getFaceId() == router1FaceId &&
160 verb == ndn::Name::Component("register"));
161
162 ++it;
163 extractRibCommandParameters(*it, verb, extractedParameters);
164
165 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
166 extractedParameters.getFaceId() == router2FaceId &&
167 verb == ndn::Name::Component("register"));
168}
169
170BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
171{
172 NextHop hop1(router1FaceUri, 10);
173 NextHop hop2(router2FaceUri, 20);
174
175 NexthopList oldHops;
176 oldHops.addNextHop(hop1);
177 oldHops.addNextHop(hop2);
178
Nick Gordon5867b522017-09-06 17:41:37 -0500179 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500180 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500181
182 BOOST_REQUIRE_EQUAL(interests.size(), 2);
183 interests.clear();
184
185 NexthopList empty;
186
Nick Gordon5867b522017-09-06 17:41:37 -0500187 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500188 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500189
190 // Should unregister faces 1 and 2 for /ndn/name
191 BOOST_CHECK_EQUAL(interests.size(), 2);
192
193 ndn::nfd::ControlParameters extractedParameters;
194 ndn::Name::Component verb;
195 std::vector<ndn::Interest>::iterator it = interests.begin();
196
197 extractRibCommandParameters(*it, verb, extractedParameters);
198
199 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
200 extractedParameters.getFaceId() == router1FaceId &&
201 verb == ndn::Name::Component("unregister"));
202
203 ++it;
204 extractRibCommandParameters(*it, verb, extractedParameters);
205
206 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
207 extractedParameters.getFaceId() == router2FaceId &&
208 verb == ndn::Name::Component("unregister"));
209}
210
211BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
212{
213 NextHop hop1(router1FaceUri, 10);
214 NextHop hop2(router2FaceUri, 20);
215 NextHop hop3(router3FaceUri, 30);
216
217 NexthopList hops;
218 hops.addNextHop(hop1);
219 hops.addNextHop(hop2);
220 hops.addNextHop(hop3);
221
Nick Gordon5867b522017-09-06 17:41:37 -0500222 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500223 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500224
225 // Should only register faces 1 and 2 for /ndn/name
226 BOOST_CHECK_EQUAL(interests.size(), 2);
227
228 ndn::nfd::ControlParameters extractedParameters;
229 ndn::Name::Component verb;
230 std::vector<ndn::Interest>::iterator it = interests.begin();
231
232 extractRibCommandParameters(*it, verb, extractedParameters);
233
234 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
235 extractedParameters.getFaceId() == router1FaceId &&
236 verb == ndn::Name::Component("register"));
237
238 ++it;
239 extractRibCommandParameters(*it, verb, extractedParameters);
240
241 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
242 extractedParameters.getFaceId() == router2FaceId &&
243 verb == ndn::Name::Component("register"));
244}
245
246BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
247{
248 NextHop hop1(router1FaceUri, 10);
249 NextHop hop2(router2FaceUri, 20);
250
251 NexthopList hops;
252 hops.addNextHop(hop1);
253 hops.addNextHop(hop2);
254
Nick Gordon5867b522017-09-06 17:41:37 -0500255 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500256 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500257
258 // FIB
259 // Name NextHops
260 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
261 BOOST_REQUIRE_EQUAL(interests.size(), 2);
262 interests.clear();
263
264 // Routing table is recalculated; a new more optimal path is found
265 NextHop hop3(router3FaceUri, 5);
266 hops.addNextHop(hop3);
267
Nick Gordon5867b522017-09-06 17:41:37 -0500268 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500269 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500270
271 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
272 // unregistered. Face 1 will also be re-registered.
273 //
274 // FIB
275 // Name NextHops
276 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
277
278 BOOST_CHECK_EQUAL(interests.size(), 3);
279
280 ndn::nfd::ControlParameters extractedParameters;
281 ndn::Name::Component verb;
282 std::vector<ndn::Interest>::iterator it = interests.begin();
283
284 extractRibCommandParameters(*it, verb, extractedParameters);
285
286 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
287 extractedParameters.getFaceId() == router3FaceId &&
288 verb == ndn::Name::Component("register"));
289
290 ++it;
291 extractRibCommandParameters(*it, verb, extractedParameters);
292
293 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
294 extractedParameters.getFaceId() == router1FaceId &&
295 verb == ndn::Name::Component("register"));
296
297 ++it;
298 extractRibCommandParameters(*it, verb, extractedParameters);
299
300 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
301 extractedParameters.getFaceId() == router2FaceId &&
302 verb == ndn::Name::Component("unregister"));
303}
304
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500305BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
306{
307 ndn::Name name1("/name/1");
308 FibEntry fe(name1);
309 fib->m_table.emplace(name1, fe);
310 int origSeqNo = fe.getSeqNo();
311
312 fib->scheduleEntryRefresh(fe,
313 [&, this] (FibEntry& entry) {
314 BOOST_CHECK_EQUAL(origSeqNo+1, entry.getSeqNo());
315 });
316 this->advanceClocks(ndn::time::milliseconds(10), 1);
317}
318
Vince Lehman942eb7b2014-10-02 10:09:27 -0500319BOOST_AUTO_TEST_SUITE_END()
320
Nick Gordonfad8e252016-08-11 14:21:38 -0500321} // namespace test
322} // namespace nlsr