blob: e0df3159d0876b02de7ec7fda3602f7240e4d8c7 [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
22#include "test-common.hpp"
23#include "control-commands.hpp"
Vince Lehman942eb7b2014-10-02 10:09:27 -050024
25#include "route/fib.hpp"
26
27#include "adjacency-list.hpp"
28#include "conf-parameter.hpp"
29
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060030#include <ndn-cxx/util/dummy-client-face.hpp>
31
Vince Lehman942eb7b2014-10-02 10:09:27 -050032namespace nlsr {
33namespace test {
34
Vince Lehman942eb7b2014-10-02 10:09:27 -050035using ndn::shared_ptr;
36
37class FibFixture : public BaseFixture
38{
39public:
40 FibFixture()
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060041 : face(make_shared<ndn::util::DummyClientFace>())
42 , interests(face->sentInterests)
Vince Lehman942eb7b2014-10-02 10:09:27 -050043 {
44 INIT_LOGGERS("/tmp", "DEBUG");
45
46 Adjacent neighbor1(router1Name, router1FaceUri, 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
47 adjacencies.insert(neighbor1);
48
49 Adjacent neighbor2(router2Name, router2FaceUri, 0, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
50 adjacencies.insert(neighbor2);
51
52 Adjacent neighbor3(router3Name, router3FaceUri, 0, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
53 adjacencies.insert(neighbor3);
54
55 conf.setMaxFacesPerPrefix(2);
56
Vince Lehmanb7079a12014-11-04 12:45:50 -060057 fib = ndn::make_shared<Fib>(ndn::ref(*face), ndn::ref(g_scheduler), ndn::ref(adjacencies),
58 ndn::ref(conf), keyChain);
Vince Lehman942eb7b2014-10-02 10:09:27 -050059
60 fib->m_faceMap.update(router1FaceUri, router1FaceId);
61 fib->m_faceMap.update(router2FaceUri, router2FaceId);
62 fib->m_faceMap.update(router3FaceUri, router3FaceId);
63 }
64
65public:
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060066 shared_ptr<ndn::util::DummyClientFace> face;
Vince Lehmanb7079a12014-11-04 12:45:50 -060067 ndn::KeyChain keyChain;
Vince Lehman942eb7b2014-10-02 10:09:27 -050068 shared_ptr<Fib> fib;
69
70 AdjacencyList adjacencies;
71 ConfParameter conf;
72 std::vector<ndn::Interest>& interests;
73
74 static const ndn::Name router1Name;
75 static const ndn::Name router2Name;
76 static const ndn::Name router3Name;
77
78 static const std::string router1FaceUri;
79 static const std::string router2FaceUri;
80 static const std::string router3FaceUri;
81
82 static const uint32_t router1FaceId;
83 static const uint32_t router2FaceId;
84 static const uint32_t router3FaceId;
85};
86
87const ndn::Name FibFixture::router1Name = "/ndn/router1";
88const ndn::Name FibFixture::router2Name = "/ndn/router2";
89const ndn::Name FibFixture::router3Name = "/ndn/router3";
90
91const std::string FibFixture::router1FaceUri = "uri://face1";
92const std::string FibFixture::router2FaceUri = "uri://face2";
93const std::string FibFixture::router3FaceUri = "uri://face3";
94
95const uint32_t FibFixture::router1FaceId = 1;
96const uint32_t FibFixture::router2FaceId = 2;
97const uint32_t FibFixture::router3FaceId = 3;
98
99BOOST_FIXTURE_TEST_SUITE(TestFib, FibFixture)
100
101BOOST_AUTO_TEST_CASE(NextHopsAdd)
102{
103 NextHop hop1(router1FaceUri, 10);
104 NextHop hop2(router2FaceUri, 20);
105
106 NexthopList hops;
107 hops.addNextHop(hop1);
108 hops.addNextHop(hop2);
109
110 fib->update("/ndn/name", hops);
111 face->processEvents(ndn::time::milliseconds(1));
112
113 // Should register faces 1 and 2 for /ndn/name
114 BOOST_REQUIRE_EQUAL(interests.size(), 2);
115
116 ndn::nfd::ControlParameters extractedParameters;
117 ndn::Name::Component verb;
118 std::vector<ndn::Interest>::iterator it = interests.begin();
119
120 extractRibCommandParameters(*it, verb, extractedParameters);
121
122 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
123 extractedParameters.getFaceId() == router1FaceId &&
124 verb == ndn::Name::Component("register"));
125
126 ++it;
127 extractRibCommandParameters(*it, verb, extractedParameters);
128
129 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
130 extractedParameters.getFaceId() == router2FaceId &&
131 verb == ndn::Name::Component("register"));
132}
133
134
135BOOST_AUTO_TEST_CASE(NextHopsNoChange)
136{
137 NextHop hop1(router1FaceUri, 10);
138 NextHop hop2(router2FaceUri, 20);
139
140 NexthopList oldHops;
141 oldHops.addNextHop(hop1);
142 oldHops.addNextHop(hop2);
143
144 fib->update("/ndn/name", oldHops);
145 face->processEvents(ndn::time::milliseconds(1));
146
147 BOOST_REQUIRE_EQUAL(interests.size(), 2);
148 interests.clear();
149
150 fib->update("/ndn/name", oldHops);
151 face->processEvents(ndn::time::milliseconds(1));
152
153 // Should register face 1 and 2 for /ndn/name
154 BOOST_REQUIRE_EQUAL(interests.size(), 2);
155
156 ndn::nfd::ControlParameters extractedParameters;
157 ndn::Name::Component verb;
158 std::vector<ndn::Interest>::iterator it = interests.begin();
159
160 extractRibCommandParameters(*it, verb, extractedParameters);
161
162 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
163 extractedParameters.getFaceId() == router1FaceId &&
164 verb == ndn::Name::Component("register"));
165
166 ++it;
167 extractRibCommandParameters(*it, verb, extractedParameters);
168
169 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
170 extractedParameters.getFaceId() == router2FaceId &&
171 verb == ndn::Name::Component("register"));
172}
173
174BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
175{
176 NextHop hop1(router1FaceUri, 10);
177 NextHop hop2(router2FaceUri, 20);
178
179 NexthopList oldHops;
180 oldHops.addNextHop(hop1);
181 oldHops.addNextHop(hop2);
182
183 fib->update("/ndn/name", oldHops);
184 face->processEvents(ndn::time::milliseconds(1));
185
186 BOOST_REQUIRE_EQUAL(interests.size(), 2);
187 interests.clear();
188
189 NexthopList empty;
190
191 fib->update("/ndn/name", empty);
192 face->processEvents(ndn::time::milliseconds(1));
193
194 // Should unregister faces 1 and 2 for /ndn/name
195 BOOST_CHECK_EQUAL(interests.size(), 2);
196
197 ndn::nfd::ControlParameters extractedParameters;
198 ndn::Name::Component verb;
199 std::vector<ndn::Interest>::iterator it = interests.begin();
200
201 extractRibCommandParameters(*it, verb, extractedParameters);
202
203 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
204 extractedParameters.getFaceId() == router1FaceId &&
205 verb == ndn::Name::Component("unregister"));
206
207 ++it;
208 extractRibCommandParameters(*it, verb, extractedParameters);
209
210 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
211 extractedParameters.getFaceId() == router2FaceId &&
212 verb == ndn::Name::Component("unregister"));
213}
214
215BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
216{
217 NextHop hop1(router1FaceUri, 10);
218 NextHop hop2(router2FaceUri, 20);
219 NextHop hop3(router3FaceUri, 30);
220
221 NexthopList hops;
222 hops.addNextHop(hop1);
223 hops.addNextHop(hop2);
224 hops.addNextHop(hop3);
225
226 fib->update("/ndn/name", hops);
227 face->processEvents(ndn::time::milliseconds(1));
228
229 // Should only register faces 1 and 2 for /ndn/name
230 BOOST_CHECK_EQUAL(interests.size(), 2);
231
232 ndn::nfd::ControlParameters extractedParameters;
233 ndn::Name::Component verb;
234 std::vector<ndn::Interest>::iterator it = interests.begin();
235
236 extractRibCommandParameters(*it, verb, extractedParameters);
237
238 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
239 extractedParameters.getFaceId() == router1FaceId &&
240 verb == ndn::Name::Component("register"));
241
242 ++it;
243 extractRibCommandParameters(*it, verb, extractedParameters);
244
245 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
246 extractedParameters.getFaceId() == router2FaceId &&
247 verb == ndn::Name::Component("register"));
248}
249
250BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
251{
252 NextHop hop1(router1FaceUri, 10);
253 NextHop hop2(router2FaceUri, 20);
254
255 NexthopList hops;
256 hops.addNextHop(hop1);
257 hops.addNextHop(hop2);
258
259 fib->update("/ndn/name", hops);
260 face->processEvents(ndn::time::milliseconds(1));
261
262 // FIB
263 // Name NextHops
264 // /ndn/name (faceId=1, cost=10), (faceId=2, cost=20)
265 BOOST_REQUIRE_EQUAL(interests.size(), 2);
266 interests.clear();
267
268 // Routing table is recalculated; a new more optimal path is found
269 NextHop hop3(router3FaceUri, 5);
270 hops.addNextHop(hop3);
271
272 fib->update("/ndn/name", hops);
273 face->processEvents(ndn::time::milliseconds(1));
274
275 // To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
276 // unregistered. Face 1 will also be re-registered.
277 //
278 // FIB
279 // Name NextHops
280 // /ndn/name (faceId=3, cost=5), (faceId=1, cost=10)
281
282 BOOST_CHECK_EQUAL(interests.size(), 3);
283
284 ndn::nfd::ControlParameters extractedParameters;
285 ndn::Name::Component verb;
286 std::vector<ndn::Interest>::iterator it = interests.begin();
287
288 extractRibCommandParameters(*it, verb, extractedParameters);
289
290 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
291 extractedParameters.getFaceId() == router3FaceId &&
292 verb == ndn::Name::Component("register"));
293
294 ++it;
295 extractRibCommandParameters(*it, verb, extractedParameters);
296
297 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
298 extractedParameters.getFaceId() == router1FaceId &&
299 verb == ndn::Name::Component("register"));
300
301 ++it;
302 extractRibCommandParameters(*it, verb, extractedParameters);
303
304 BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
305 extractedParameters.getFaceId() == router2FaceId &&
306 verb == ndn::Name::Component("unregister"));
307}
308
309BOOST_AUTO_TEST_SUITE_END()
310
Nick Gordonfad8e252016-08-11 14:21:38 -0500311} // namespace test
312} // namespace nlsr