blob: 94a37af46cc35b54ff12acb594458c81a8607b13 [file] [log] [blame]
Vince Lehman72446ec2014-07-09 10:50:02 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08003 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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.
Vince Lehman72446ec2014-07-09 10:50:02 -050010 *
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 "rib/rib-manager.hpp"
Junxiao Shi376f7372014-11-17 18:03:31 -070027#include <ndn-cxx/management/nfd-face-status.hpp>
Vince Lehmancd16c832014-07-23 15:14:55 -070028#include "rib/rib-status-publisher-common.hpp"
Vince Lehman72446ec2014-07-09 10:50:02 -050029
Junxiao Shi376f7372014-11-17 18:03:31 -070030#include "tests/test-common.hpp"
31#include "tests/limited-io.hpp"
32#include <ndn-cxx/util/dummy-client-face.hpp>
Vince Lehman26b215c2014-08-17 15:00:41 -050033
Vince Lehman72446ec2014-07-09 10:50:02 -050034namespace nfd {
35namespace rib {
36namespace tests {
37
38class RibManagerFixture : public nfd::tests::BaseFixture
39{
40public:
41 RibManagerFixture()
42 : COMMAND_PREFIX("/localhost/nfd/rib")
43 , ADD_NEXTHOP_VERB("add-nexthop")
44 , REMOVE_NEXTHOP_VERB("remove-nexthop")
Vince Lehman76c751c2014-11-18 17:36:38 -060045 , REGISTER_COMMAND("/localhost/nfd/rib/register")
46 , UNREGISTER_COMMAND("/localhost/nfd/rib/unregister")
Vince Lehman72446ec2014-07-09 10:50:02 -050047 {
Junxiao Shi376f7372014-11-17 18:03:31 -070048 face = ndn::util::makeDummyClientFace();
Vince Lehman72446ec2014-07-09 10:50:02 -050049
Vince Lehmanc1dfdb42015-07-16 12:17:36 -050050 manager = make_shared<RibManager>(*face, keyChain);
Vince Lehman72446ec2014-07-09 10:50:02 -050051 manager->registerWithNfd();
52
53 face->processEvents(time::milliseconds(1));
Junxiao Shi376f7372014-11-17 18:03:31 -070054 face->sentInterests.clear();
Vince Lehman72446ec2014-07-09 10:50:02 -050055 }
56
57 ~RibManagerFixture()
58 {
59 manager.reset();
60 face.reset();
61 }
62
Vince Lehman76c751c2014-11-18 17:36:38 -060063 void
64 extractParameters(Interest& interest, Name::Component& verb,
65 ControlParameters& extractedParameters)
Vince Lehman72446ec2014-07-09 10:50:02 -050066 {
67 const Name& name = interest.getName();
68 verb = name[COMMAND_PREFIX.size()];
69 const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1];
70
71 Block rawParameters = parameterComponent.blockFromValue();
72 extractedParameters.wireDecode(rawParameters);
73 }
74
Vince Lehman76c751c2014-11-18 17:36:38 -060075 void
76 receiveCommandInterest(const Name& name, ControlParameters& parameters)
Vince Lehman72446ec2014-07-09 10:50:02 -050077 {
Vince Lehman76c751c2014-11-18 17:36:38 -060078 Name commandName = name;
79 commandName.append(parameters.wireEncode());
Vince Lehman72446ec2014-07-09 10:50:02 -050080
Vince Lehman76c751c2014-11-18 17:36:38 -060081 Interest commandInterest(commandName);
Vince Lehman72446ec2014-07-09 10:50:02 -050082
Vince Lehman76c751c2014-11-18 17:36:38 -060083 manager->m_managedRib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue,
84 this, _1, parameters);
85
86 face->receive(commandInterest);
Vince Lehman72446ec2014-07-09 10:50:02 -050087 face->processEvents(time::milliseconds(1));
88 }
89
Vince Lehman76c751c2014-11-18 17:36:38 -060090 void
91 onSendBatchFromQueue(const RibUpdateBatch& batch, const ControlParameters parameters)
92 {
93 BOOST_REQUIRE(batch.begin() != batch.end());
94 RibUpdate update = *(batch.begin());
95
96 Rib::UpdateSuccessCallback managerCallback =
97 bind(&RibManager::onRibUpdateSuccess, manager, update);
98
99 Rib& rib = manager->m_managedRib;
100
101 // Simulate a successful response from NFD
102 FibUpdater& updater = manager->m_fibUpdater;
103 rib.onFibUpdateSuccess(batch, updater.m_inheritedRoutes, managerCallback);
104 }
105
106
Vince Lehman72446ec2014-07-09 10:50:02 -0500107public:
108 shared_ptr<RibManager> manager;
Junxiao Shi376f7372014-11-17 18:03:31 -0700109 shared_ptr<ndn::util::DummyClientFace> face;
Vince Lehmanc1dfdb42015-07-16 12:17:36 -0500110 ndn::KeyChain keyChain;
Vince Lehman72446ec2014-07-09 10:50:02 -0500111
112 const Name COMMAND_PREFIX;
113 const Name::Component ADD_NEXTHOP_VERB;
114 const Name::Component REMOVE_NEXTHOP_VERB;
Vince Lehman76c751c2014-11-18 17:36:38 -0600115
116 const Name REGISTER_COMMAND;
117 const Name UNREGISTER_COMMAND;
Vince Lehman72446ec2014-07-09 10:50:02 -0500118};
119
120class AuthorizedRibManager : public RibManagerFixture
121{
122public:
123 AuthorizedRibManager()
124 {
125 ConfigFile config;
126 manager->setConfigFile(config);
127
128 const std::string CONFIG_STRING =
129 "rib\n"
130 "{\n"
131 " localhost_security\n"
132 " {\n"
133 " trust-anchor\n"
134 " {\n"
135 " type any\n"
136 " }\n"
137 " }"
138 "}";
139
140 config.parse(CONFIG_STRING, true, "test-rib");
141 }
142};
143
144typedef RibManagerFixture UnauthorizedRibManager;
145
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -0800146BOOST_FIXTURE_TEST_SUITE(TestRibManager, RibManagerFixture)
Vince Lehman72446ec2014-07-09 10:50:02 -0500147
Steve DiBenedettocd4ee5f2014-12-08 16:09:11 -0700148BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
149{
150 Name commandName("/localhost/nfd/rib");
Vince Lehman76c751c2014-11-18 17:36:38 -0600151 ndn::nfd::ControlParameters parameters;
152
153 receiveCommandInterest(commandName, parameters);
Steve DiBenedettocd4ee5f2014-12-08 16:09:11 -0700154 // TODO verify error response
155}
156
Vince Lehman72446ec2014-07-09 10:50:02 -0500157BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager)
158{
159 ControlParameters parameters;
160 parameters
161 .setName("/hello")
162 .setFaceId(1)
163 .setCost(10)
164 .setFlags(0)
165 .setOrigin(128)
166 .setExpirationPeriod(ndn::time::milliseconds::max());
167
Vince Lehman76c751c2014-11-18 17:36:38 -0600168 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500169
Junxiao Shi376f7372014-11-17 18:03:31 -0700170 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500171}
172
173BOOST_FIXTURE_TEST_CASE(Register, AuthorizedRibManager)
174{
175 ControlParameters parameters;
176 parameters
177 .setName("/hello")
178 .setFaceId(1)
179 .setCost(10)
180 .setFlags(0)
181 .setOrigin(128)
182 .setExpirationPeriod(ndn::time::milliseconds::max());
183
Vince Lehman76c751c2014-11-18 17:36:38 -0600184 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500185
Junxiao Shi376f7372014-11-17 18:03:31 -0700186 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500187
Junxiao Shi376f7372014-11-17 18:03:31 -0700188 Interest& request = face->sentInterests[0];
Vince Lehman72446ec2014-07-09 10:50:02 -0500189
190 ControlParameters extractedParameters;
191 Name::Component verb;
192 extractParameters(request, verb, extractedParameters);
193
194 BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
195 BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
196 BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), parameters.getFaceId());
197 BOOST_CHECK_EQUAL(extractedParameters.getCost(), parameters.getCost());
198}
199
200BOOST_FIXTURE_TEST_CASE(Unregister, AuthorizedRibManager)
201{
202 ControlParameters addParameters;
203 addParameters
204 .setName("/hello")
205 .setFaceId(1)
206 .setCost(10)
207 .setFlags(0)
208 .setOrigin(128)
209 .setExpirationPeriod(ndn::time::milliseconds::max());
210
Vince Lehman76c751c2014-11-18 17:36:38 -0600211 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Junxiao Shi376f7372014-11-17 18:03:31 -0700212 face->sentInterests.clear();
Vince Lehman72446ec2014-07-09 10:50:02 -0500213
214 ControlParameters removeParameters;
215 removeParameters
216 .setName("/hello")
217 .setFaceId(1)
218 .setOrigin(128);
219
Vince Lehman76c751c2014-11-18 17:36:38 -0600220 receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500221
Junxiao Shi376f7372014-11-17 18:03:31 -0700222 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500223
Junxiao Shi376f7372014-11-17 18:03:31 -0700224 Interest& request = face->sentInterests[0];
Vince Lehman72446ec2014-07-09 10:50:02 -0500225
226 ControlParameters extractedParameters;
227 Name::Component verb;
228 extractParameters(request, verb, extractedParameters);
229
230 BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
231 BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
232 BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
233}
234
Vince Lehman76c751c2014-11-18 17:36:38 -0600235
Vince Lehman72446ec2014-07-09 10:50:02 -0500236BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
237{
238 ControlParameters parameters;
239 parameters
240 .setName("/hello")
241 .setFaceId(1)
242 .setCost(10)
243 .setFlags(0)
244 .setOrigin(128)
245 .setExpirationPeriod(ndn::time::milliseconds::max());
246
Junxiao Shi376f7372014-11-17 18:03:31 -0700247 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
Vince Lehman72446ec2014-07-09 10:50:02 -0500248
Vince Lehman76c751c2014-11-18 17:36:38 -0600249 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500250
Junxiao Shi376f7372014-11-17 18:03:31 -0700251 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
Vince Lehman72446ec2014-07-09 10:50:02 -0500252}
253
Vince Lehmancd16c832014-07-23 15:14:55 -0700254BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager)
255{
Vince Lehman76c751c2014-11-18 17:36:38 -0600256 Name prefix("/");
257
Vince Lehman218be0a2015-01-15 17:25:20 -0600258 Route route;
Vince Lehman218be0a2015-01-15 17:25:20 -0600259 route.faceId = 1;
260 route.origin = 128;
261 route.cost = 32;
262 route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE;
Vince Lehmancd16c832014-07-23 15:14:55 -0700263
Vince Lehman76c751c2014-11-18 17:36:38 -0600264 manager->m_managedRib.insert(prefix, route);
Vince Lehmancd16c832014-07-23 15:14:55 -0700265
266 face->receive(Interest("/localhost/nfd/rib/list"));
267 face->processEvents(time::milliseconds(1));
268
Junxiao Shi376f7372014-11-17 18:03:31 -0700269 BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
Vince Lehman76c751c2014-11-18 17:36:38 -0600270 RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
Vince Lehmancd16c832014-07-23 15:14:55 -0700271}
272
Vince Lehman281ded72014-08-21 12:17:08 -0500273BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager)
274{
Vince Lehman76c751c2014-11-18 17:36:38 -0600275 // Register route
Vince Lehman281ded72014-08-21 12:17:08 -0500276 ControlParameters addParameters;
277 addParameters
278 .setName("/expire")
279 .setFaceId(1)
280 .setCost(10)
281 .setFlags(0)
282 .setOrigin(128)
283 .setExpirationPeriod(ndn::time::milliseconds(500));
284
Vince Lehman76c751c2014-11-18 17:36:38 -0600285 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Junxiao Shi376f7372014-11-17 18:03:31 -0700286 face->sentInterests.clear();
Vince Lehman281ded72014-08-21 12:17:08 -0500287
Vince Lehman76c751c2014-11-18 17:36:38 -0600288 // Unregister route
Vince Lehman281ded72014-08-21 12:17:08 -0500289 ControlParameters removeParameters;
290 removeParameters
291 .setName("/expire")
292 .setFaceId(1)
293 .setOrigin(128);
294
Vince Lehman76c751c2014-11-18 17:36:38 -0600295 receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
Vince Lehman281ded72014-08-21 12:17:08 -0500296
Vince Lehman76c751c2014-11-18 17:36:38 -0600297 // Reregister route
Vince Lehman281ded72014-08-21 12:17:08 -0500298 addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
Vince Lehman76c751c2014-11-18 17:36:38 -0600299 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Vince Lehman281ded72014-08-21 12:17:08 -0500300
301 nfd::tests::LimitedIo limitedIo;
302 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
303
304 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
305}
306
Vince Lehman26b215c2014-08-17 15:00:41 -0500307BOOST_FIXTURE_TEST_CASE(RemoveInvalidFaces, AuthorizedRibManager)
308{
309 // Register valid face
310 ControlParameters validParameters;
311 validParameters
312 .setName("/test")
313 .setFaceId(1);
314
Vince Lehman76c751c2014-11-18 17:36:38 -0600315 receiveCommandInterest(REGISTER_COMMAND, validParameters);
Vince Lehman26b215c2014-08-17 15:00:41 -0500316
317 // Register invalid face
318 ControlParameters invalidParameters;
319 invalidParameters
320 .setName("/test")
321 .setFaceId(2);
322
Vince Lehman76c751c2014-11-18 17:36:38 -0600323 receiveCommandInterest(REGISTER_COMMAND, invalidParameters);
Vince Lehman26b215c2014-08-17 15:00:41 -0500324
325 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2);
326
327 // Receive status with only faceId: 1
328 ndn::nfd::FaceStatus status;
329 status.setFaceId(1);
330
331 shared_ptr<Data> data = nfd::tests::makeData("/localhost/nfd/faces/list");
332 data->setContent(status.wireEncode());
333
334 shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
335 buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
336 data->getContent().value_size());
337
338 manager->removeInvalidFaces(buffer);
339
340 // Run scheduler
341 nfd::tests::LimitedIo limitedIo;
342 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
343
344 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
345
346 Rib::const_iterator it = manager->m_managedRib.find("/test");
347 BOOST_REQUIRE(it != manager->m_managedRib.end());
348
349 shared_ptr<RibEntry> entry = it->second;
350 BOOST_CHECK_EQUAL(entry->hasFaceId(1), true);
351 BOOST_CHECK_EQUAL(entry->hasFaceId(2), false);
352}
353
Vince Lehman7c7d33a2015-01-20 17:40:26 -0600354BOOST_FIXTURE_TEST_CASE(LocalHopInherit, AuthorizedRibManager)
355{
356 using nfd::rib::RibManager;
357
358 // Simulate NFD response
359 ControlParameters result;
360 result.setFaceId(261);
361
362 manager->onNrdCommandPrefixAddNextHopSuccess(RibManager::REMOTE_COMMAND_PREFIX, result);
363
364 // Register route that localhop prefix should inherit
365 ControlParameters parameters;
366 parameters
367 .setName("/localhop/nfd")
368 .setFaceId(262)
369 .setCost(25)
370 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
371
372 Name commandName("/localhost/nfd/rib/register");
373
374 receiveCommandInterest(commandName, parameters);
375
376 // REMOTE_COMMAND_PREFIX should have its original route and the inherited route
377 auto it = manager->m_managedRib.find(RibManager::REMOTE_COMMAND_PREFIX);
378
379 BOOST_REQUIRE(it != manager->m_managedRib.end());
380 const RibEntry::RouteList& inheritedRoutes = (*(it->second)).getInheritedRoutes();
381
382 BOOST_CHECK_EQUAL(inheritedRoutes.size(), 1);
383 auto routeIt = inheritedRoutes.begin();
384
385 BOOST_CHECK_EQUAL(routeIt->faceId, 262);
386 BOOST_CHECK_EQUAL(routeIt->cost, 25);
387}
388
Vince Lehman76c751c2014-11-18 17:36:38 -0600389BOOST_FIXTURE_TEST_CASE(RouteExpiration, AuthorizedRibManager)
390{
391 // Register route
392 ControlParameters parameters;
393 parameters.setName("/expire")
394 .setExpirationPeriod(ndn::time::milliseconds(500));
395
396 receiveCommandInterest(REGISTER_COMMAND, parameters);
397 face->sentInterests.clear();
398
399 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
400
401 // Route should expire
402 nfd::tests::LimitedIo limitedIo;
403 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
404
405 BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
406}
407
408BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, AuthorizedRibManager)
409{
410 uint64_t faceToDestroy = 128;
411
412 // Register valid face
413 ControlParameters parameters;
414 parameters.setName("/test")
415 .setFaceId(faceToDestroy);
416
417 receiveCommandInterest(REGISTER_COMMAND, parameters);
418 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
419
420 // Don't respond with a success message from the FIB
421 manager->m_managedRib.m_onSendBatchFromQueue = nullptr;
422
423 manager->onFaceDestroyedEvent(faceToDestroy);
424 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 0);
425}
426
Vince Lehman72446ec2014-07-09 10:50:02 -0500427BOOST_AUTO_TEST_SUITE_END()
428
429} // namespace tests
430} // namespace rib
431} // namespace nfd