blob: 84642f1a4409ee5066ba1fef5ea05d78b9173a53 [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()
dmcoomes9f936662017-03-02 10:33:09 -060039 : face(std::make_shared<ndn::util::DummyClientFace>())
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
Nick Gordone9733ed2017-04-26 10:48:39 -050044 Adjacent neighbor1(router1Name, ndn::util::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050045 adjacencies.insert(neighbor1);
46
Nick Gordone9733ed2017-04-26 10:48:39 -050047 Adjacent neighbor2(router2Name, ndn::util::FaceUri(router2FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
Vince Lehman942eb7b2014-10-02 10:09:27 -050048 adjacencies.insert(neighbor2);
49
Nick Gordone9733ed2017-04-26 10:48:39 -050050 Adjacent neighbor3(router3Name, ndn::util::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
dmcoomes9f936662017-03-02 10:33:09 -060055 fib = std::make_shared<Fib>(std::ref(*face), std::ref(g_scheduler), std::ref(adjacencies),
56 std::ref(conf), keyChain);
Vince Lehman942eb7b2014-10-02 10:09:27 -050057
58 fib->m_faceMap.update(router1FaceUri, router1FaceId);
59 fib->m_faceMap.update(router2FaceUri, router2FaceId);
60 fib->m_faceMap.update(router3FaceUri, router3FaceId);
61 }
62
63public:
dmcoomes9f936662017-03-02 10:33:09 -060064 std::shared_ptr<ndn::util::DummyClientFace> face;
Vince Lehmanb7079a12014-11-04 12:45:50 -060065 ndn::KeyChain keyChain;
dmcoomes9f936662017-03-02 10:33:09 -060066 std::shared_ptr<Fib> fib;
Vince Lehman942eb7b2014-10-02 10:09:27 -050067
68 AdjacencyList adjacencies;
69 ConfParameter conf;
70 std::vector<ndn::Interest>& interests;
71
72 static const ndn::Name router1Name;
73 static const ndn::Name router2Name;
74 static const ndn::Name router3Name;
75
76 static const std::string router1FaceUri;
77 static const std::string router2FaceUri;
78 static const std::string router3FaceUri;
79
80 static const uint32_t router1FaceId;
81 static const uint32_t router2FaceId;
82 static const uint32_t router3FaceId;
83};
84
85const ndn::Name FibFixture::router1Name = "/ndn/router1";
86const ndn::Name FibFixture::router2Name = "/ndn/router2";
87const ndn::Name FibFixture::router3Name = "/ndn/router3";
88
Nick Gordone9733ed2017-04-26 10:48:39 -050089const std::string FibFixture::router1FaceUri = "udp4://10.0.0.1";
90const std::string FibFixture::router2FaceUri = "udp4://10.0.0.2";
91const std::string FibFixture::router3FaceUri = "udp4://10.0.0.3";
Vince Lehman942eb7b2014-10-02 10:09:27 -050092
93const uint32_t FibFixture::router1FaceId = 1;
94const uint32_t FibFixture::router2FaceId = 2;
95const uint32_t FibFixture::router3FaceId = 3;
96
97BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
98
99BOOST_AUTO_TEST_CASE(NextHopsAdd)
100{
101 NextHop hop1(router1FaceUri, 10);
102 NextHop hop2(router2FaceUri, 20);
103
104 NexthopList hops;
105 hops.addNextHop(hop1);
106 hops.addNextHop(hop2);
107
Nick Gordon5867b522017-09-06 17:41:37 -0500108 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500109 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500110
111 // Should register faces 1 and 2 for /ndn/name
112 BOOST_REQUIRE_EQUAL(interests.size(), 2);
113
114 ndn::nfd::ControlParameters extractedParameters;
115 ndn::Name::Component verb;
116 std::vector<ndn::Interest>::iterator it = interests.begin();
117
118 extractRibCommandParameters(*it, verb, extractedParameters);
119
120 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
121 extractedParameters.getFaceId() == router1FaceId &&
122 verb == ndn::Name::Component("register"));
123
124 ++it;
125 extractRibCommandParameters(*it, verb, extractedParameters);
126
127 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
128 extractedParameters.getFaceId() == router2FaceId &&
129 verb == ndn::Name::Component("register"));
130}
131
132
133BOOST_AUTO_TEST_CASE(NextHopsNoChange)
134{
135 NextHop hop1(router1FaceUri, 10);
136 NextHop hop2(router2FaceUri, 20);
137
138 NexthopList oldHops;
139 oldHops.addNextHop(hop1);
140 oldHops.addNextHop(hop2);
141
Nick Gordon5867b522017-09-06 17:41:37 -0500142 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500143 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500144
145 BOOST_REQUIRE_EQUAL(interests.size(), 2);
146 interests.clear();
147
Nick Gordon5867b522017-09-06 17:41:37 -0500148 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500149 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500150
151 // Should register face 1 and 2 for /ndn/name
152 BOOST_REQUIRE_EQUAL(interests.size(), 2);
153
154 ndn::nfd::ControlParameters extractedParameters;
155 ndn::Name::Component verb;
156 std::vector<ndn::Interest>::iterator it = interests.begin();
157
158 extractRibCommandParameters(*it, verb, extractedParameters);
159
160 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
161 extractedParameters.getFaceId() == router1FaceId &&
162 verb == ndn::Name::Component("register"));
163
164 ++it;
165 extractRibCommandParameters(*it, verb, extractedParameters);
166
167 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
168 extractedParameters.getFaceId() == router2FaceId &&
169 verb == ndn::Name::Component("register"));
170}
171
172BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
173{
174 NextHop hop1(router1FaceUri, 10);
175 NextHop hop2(router2FaceUri, 20);
176
177 NexthopList oldHops;
178 oldHops.addNextHop(hop1);
179 oldHops.addNextHop(hop2);
180
Nick Gordon5867b522017-09-06 17:41:37 -0500181 fib->update("/ndn/name", oldHops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500182 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500183
184 BOOST_REQUIRE_EQUAL(interests.size(), 2);
185 interests.clear();
186
187 NexthopList empty;
188
Nick Gordon5867b522017-09-06 17:41:37 -0500189 fib->update("/ndn/name", empty);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500190 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500191
192 // Should unregister faces 1 and 2 for /ndn/name
193 BOOST_CHECK_EQUAL(interests.size(), 2);
194
195 ndn::nfd::ControlParameters extractedParameters;
196 ndn::Name::Component verb;
197 std::vector<ndn::Interest>::iterator it = interests.begin();
198
199 extractRibCommandParameters(*it, verb, extractedParameters);
200
201 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
202 extractedParameters.getFaceId() == router1FaceId &&
203 verb == ndn::Name::Component("unregister"));
204
205 ++it;
206 extractRibCommandParameters(*it, verb, extractedParameters);
207
208 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
209 extractedParameters.getFaceId() == router2FaceId &&
210 verb == ndn::Name::Component("unregister"));
211}
212
213BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
214{
215 NextHop hop1(router1FaceUri, 10);
216 NextHop hop2(router2FaceUri, 20);
217 NextHop hop3(router3FaceUri, 30);
218
219 NexthopList hops;
220 hops.addNextHop(hop1);
221 hops.addNextHop(hop2);
222 hops.addNextHop(hop3);
223
Nick Gordon5867b522017-09-06 17:41:37 -0500224 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500225 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500226
227 // Should only register faces 1 and 2 for /ndn/name
228 BOOST_CHECK_EQUAL(interests.size(), 2);
229
230 ndn::nfd::ControlParameters extractedParameters;
231 ndn::Name::Component verb;
232 std::vector<ndn::Interest>::iterator it = interests.begin();
233
234 extractRibCommandParameters(*it, verb, extractedParameters);
235
236 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
237 extractedParameters.getFaceId() == router1FaceId &&
238 verb == ndn::Name::Component("register"));
239
240 ++it;
241 extractRibCommandParameters(*it, verb, extractedParameters);
242
243 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
244 extractedParameters.getFaceId() == router2FaceId &&
245 verb == ndn::Name::Component("register"));
246}
247
248BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
249{
250 NextHop hop1(router1FaceUri, 10);
251 NextHop hop2(router2FaceUri, 20);
252
253 NexthopList hops;
254 hops.addNextHop(hop1);
255 hops.addNextHop(hop2);
256
Nick Gordon5867b522017-09-06 17:41:37 -0500257 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500258 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500259
260 // FIB
261 // Name NextHops
262 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
263 BOOST_REQUIRE_EQUAL(interests.size(), 2);
264 interests.clear();
265
266 // Routing table is recalculated; a new more optimal path is found
267 NextHop hop3(router3FaceUri, 5);
268 hops.addNextHop(hop3);
269
Nick Gordon5867b522017-09-06 17:41:37 -0500270 fib->update("/ndn/name", hops);
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500271 face->processEvents(ndn::time::milliseconds(-1));
Vince Lehman942eb7b2014-10-02 10:09:27 -0500272
273 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
274 // unregistered. Face 1 will also be re-registered.
275 //
276 // FIB
277 // Name NextHops
278 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
279
280 BOOST_CHECK_EQUAL(interests.size(), 3);
281
282 ndn::nfd::ControlParameters extractedParameters;
283 ndn::Name::Component verb;
284 std::vector<ndn::Interest>::iterator it = interests.begin();
285
286 extractRibCommandParameters(*it, verb, extractedParameters);
287
288 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
289 extractedParameters.getFaceId() == router3FaceId &&
290 verb == ndn::Name::Component("register"));
291
292 ++it;
293 extractRibCommandParameters(*it, verb, extractedParameters);
294
295 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
296 extractedParameters.getFaceId() == router1FaceId &&
297 verb == ndn::Name::Component("register"));
298
299 ++it;
300 extractRibCommandParameters(*it, verb, extractedParameters);
301
302 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
303 extractedParameters.getFaceId() == router2FaceId &&
304 verb == ndn::Name::Component("unregister"));
305}
306
Muktadir Chowdhury3be64662015-05-01 14:50:53 -0500307BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
308{
309 ndn::Name name1("/name/1");
310 FibEntry fe(name1);
311 fib->m_table.emplace(name1, fe);
312 int origSeqNo = fe.getSeqNo();
313
314 fib->scheduleEntryRefresh(fe,
315 [&, this] (FibEntry& entry) {
316 BOOST_CHECK_EQUAL(origSeqNo+1, entry.getSeqNo());
317 });
318 this->advanceClocks(ndn::time::milliseconds(10), 1);
319}
320
Vince Lehman942eb7b2014-10-02 10:09:27 -0500321BOOST_AUTO_TEST_SUITE_END()
322
Nick Gordonfad8e252016-08-11 14:21:38 -0500323} // namespace test
324} // namespace nlsr