blob: cfce38b19a71df00953bc625f1ab1922795f33f2 [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
50 manager = make_shared<RibManager>(ndn::ref(*face));
51 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 Lehman72446ec2014-07-09 10:50:02 -0500110
111 const Name COMMAND_PREFIX;
112 const Name::Component ADD_NEXTHOP_VERB;
113 const Name::Component REMOVE_NEXTHOP_VERB;
Vince Lehman76c751c2014-11-18 17:36:38 -0600114
115 const Name REGISTER_COMMAND;
116 const Name UNREGISTER_COMMAND;
Vince Lehman72446ec2014-07-09 10:50:02 -0500117};
118
119class AuthorizedRibManager : public RibManagerFixture
120{
121public:
122 AuthorizedRibManager()
123 {
124 ConfigFile config;
125 manager->setConfigFile(config);
126
127 const std::string CONFIG_STRING =
128 "rib\n"
129 "{\n"
130 " localhost_security\n"
131 " {\n"
132 " trust-anchor\n"
133 " {\n"
134 " type any\n"
135 " }\n"
136 " }"
137 "}";
138
139 config.parse(CONFIG_STRING, true, "test-rib");
140 }
141};
142
143typedef RibManagerFixture UnauthorizedRibManager;
144
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -0800145BOOST_FIXTURE_TEST_SUITE(TestRibManager, RibManagerFixture)
Vince Lehman72446ec2014-07-09 10:50:02 -0500146
Steve DiBenedettocd4ee5f2014-12-08 16:09:11 -0700147BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
148{
149 Name commandName("/localhost/nfd/rib");
Vince Lehman76c751c2014-11-18 17:36:38 -0600150 ndn::nfd::ControlParameters parameters;
151
152 receiveCommandInterest(commandName, parameters);
Steve DiBenedettocd4ee5f2014-12-08 16:09:11 -0700153 // TODO verify error response
154}
155
Vince Lehman72446ec2014-07-09 10:50:02 -0500156BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager)
157{
158 ControlParameters parameters;
159 parameters
160 .setName("/hello")
161 .setFaceId(1)
162 .setCost(10)
163 .setFlags(0)
164 .setOrigin(128)
165 .setExpirationPeriod(ndn::time::milliseconds::max());
166
Vince Lehman76c751c2014-11-18 17:36:38 -0600167 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500168
Junxiao Shi376f7372014-11-17 18:03:31 -0700169 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500170}
171
172BOOST_FIXTURE_TEST_CASE(Register, AuthorizedRibManager)
173{
174 ControlParameters parameters;
175 parameters
176 .setName("/hello")
177 .setFaceId(1)
178 .setCost(10)
179 .setFlags(0)
180 .setOrigin(128)
181 .setExpirationPeriod(ndn::time::milliseconds::max());
182
Vince Lehman76c751c2014-11-18 17:36:38 -0600183 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500184
Junxiao Shi376f7372014-11-17 18:03:31 -0700185 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500186
Junxiao Shi376f7372014-11-17 18:03:31 -0700187 Interest& request = face->sentInterests[0];
Vince Lehman72446ec2014-07-09 10:50:02 -0500188
189 ControlParameters extractedParameters;
190 Name::Component verb;
191 extractParameters(request, verb, extractedParameters);
192
193 BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
194 BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
195 BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), parameters.getFaceId());
196 BOOST_CHECK_EQUAL(extractedParameters.getCost(), parameters.getCost());
197}
198
199BOOST_FIXTURE_TEST_CASE(Unregister, AuthorizedRibManager)
200{
201 ControlParameters addParameters;
202 addParameters
203 .setName("/hello")
204 .setFaceId(1)
205 .setCost(10)
206 .setFlags(0)
207 .setOrigin(128)
208 .setExpirationPeriod(ndn::time::milliseconds::max());
209
Vince Lehman76c751c2014-11-18 17:36:38 -0600210 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Junxiao Shi376f7372014-11-17 18:03:31 -0700211 face->sentInterests.clear();
Vince Lehman72446ec2014-07-09 10:50:02 -0500212
213 ControlParameters removeParameters;
214 removeParameters
215 .setName("/hello")
216 .setFaceId(1)
217 .setOrigin(128);
218
Vince Lehman76c751c2014-11-18 17:36:38 -0600219 receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500220
Junxiao Shi376f7372014-11-17 18:03:31 -0700221 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
Vince Lehman72446ec2014-07-09 10:50:02 -0500222
Junxiao Shi376f7372014-11-17 18:03:31 -0700223 Interest& request = face->sentInterests[0];
Vince Lehman72446ec2014-07-09 10:50:02 -0500224
225 ControlParameters extractedParameters;
226 Name::Component verb;
227 extractParameters(request, verb, extractedParameters);
228
229 BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
230 BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
231 BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
232}
233
Vince Lehman76c751c2014-11-18 17:36:38 -0600234
Vince Lehman72446ec2014-07-09 10:50:02 -0500235BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
236{
237 ControlParameters parameters;
238 parameters
239 .setName("/hello")
240 .setFaceId(1)
241 .setCost(10)
242 .setFlags(0)
243 .setOrigin(128)
244 .setExpirationPeriod(ndn::time::milliseconds::max());
245
Junxiao Shi376f7372014-11-17 18:03:31 -0700246 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
Vince Lehman72446ec2014-07-09 10:50:02 -0500247
Vince Lehman76c751c2014-11-18 17:36:38 -0600248 receiveCommandInterest(REGISTER_COMMAND, parameters);
Vince Lehman72446ec2014-07-09 10:50:02 -0500249
Junxiao Shi376f7372014-11-17 18:03:31 -0700250 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
Vince Lehman72446ec2014-07-09 10:50:02 -0500251}
252
Vince Lehmancd16c832014-07-23 15:14:55 -0700253BOOST_FIXTURE_TEST_CASE(RibStatusRequest, AuthorizedRibManager)
254{
Vince Lehman76c751c2014-11-18 17:36:38 -0600255 Name prefix("/");
256
Vince Lehman218be0a2015-01-15 17:25:20 -0600257 Route route;
Vince Lehman218be0a2015-01-15 17:25:20 -0600258 route.faceId = 1;
259 route.origin = 128;
260 route.cost = 32;
261 route.flags = ndn::nfd::ROUTE_FLAG_CAPTURE;
Vince Lehmancd16c832014-07-23 15:14:55 -0700262
Vince Lehman76c751c2014-11-18 17:36:38 -0600263 manager->m_managedRib.insert(prefix, route);
Vince Lehmancd16c832014-07-23 15:14:55 -0700264
265 face->receive(Interest("/localhost/nfd/rib/list"));
266 face->processEvents(time::milliseconds(1));
267
Junxiao Shi376f7372014-11-17 18:03:31 -0700268 BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
Vince Lehman76c751c2014-11-18 17:36:38 -0600269 RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
Vince Lehmancd16c832014-07-23 15:14:55 -0700270}
271
Vince Lehman281ded72014-08-21 12:17:08 -0500272BOOST_FIXTURE_TEST_CASE(CancelExpirationEvent, AuthorizedRibManager)
273{
Vince Lehman76c751c2014-11-18 17:36:38 -0600274 // Register route
Vince Lehman281ded72014-08-21 12:17:08 -0500275 ControlParameters addParameters;
276 addParameters
277 .setName("/expire")
278 .setFaceId(1)
279 .setCost(10)
280 .setFlags(0)
281 .setOrigin(128)
282 .setExpirationPeriod(ndn::time::milliseconds(500));
283
Vince Lehman76c751c2014-11-18 17:36:38 -0600284 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Junxiao Shi376f7372014-11-17 18:03:31 -0700285 face->sentInterests.clear();
Vince Lehman281ded72014-08-21 12:17:08 -0500286
Vince Lehman76c751c2014-11-18 17:36:38 -0600287 // Unregister route
Vince Lehman281ded72014-08-21 12:17:08 -0500288 ControlParameters removeParameters;
289 removeParameters
290 .setName("/expire")
291 .setFaceId(1)
292 .setOrigin(128);
293
Vince Lehman76c751c2014-11-18 17:36:38 -0600294 receiveCommandInterest(UNREGISTER_COMMAND, removeParameters);
Vince Lehman281ded72014-08-21 12:17:08 -0500295
Vince Lehman76c751c2014-11-18 17:36:38 -0600296 // Reregister route
Vince Lehman281ded72014-08-21 12:17:08 -0500297 addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
Vince Lehman76c751c2014-11-18 17:36:38 -0600298 receiveCommandInterest(REGISTER_COMMAND, addParameters);
Vince Lehman281ded72014-08-21 12:17:08 -0500299
300 nfd::tests::LimitedIo limitedIo;
301 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
302
303 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
304}
305
Vince Lehman26b215c2014-08-17 15:00:41 -0500306BOOST_FIXTURE_TEST_CASE(RemoveInvalidFaces, AuthorizedRibManager)
307{
308 // Register valid face
309 ControlParameters validParameters;
310 validParameters
311 .setName("/test")
312 .setFaceId(1);
313
Vince Lehman76c751c2014-11-18 17:36:38 -0600314 receiveCommandInterest(REGISTER_COMMAND, validParameters);
Vince Lehman26b215c2014-08-17 15:00:41 -0500315
316 // Register invalid face
317 ControlParameters invalidParameters;
318 invalidParameters
319 .setName("/test")
320 .setFaceId(2);
321
Vince Lehman76c751c2014-11-18 17:36:38 -0600322 receiveCommandInterest(REGISTER_COMMAND, invalidParameters);
Vince Lehman26b215c2014-08-17 15:00:41 -0500323
324 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 2);
325
326 // Receive status with only faceId: 1
327 ndn::nfd::FaceStatus status;
328 status.setFaceId(1);
329
330 shared_ptr<Data> data = nfd::tests::makeData("/localhost/nfd/faces/list");
331 data->setContent(status.wireEncode());
332
333 shared_ptr<ndn::OBufferStream> buffer = make_shared<ndn::OBufferStream>();
334 buffer->write(reinterpret_cast<const char*>(data->getContent().value()),
335 data->getContent().value_size());
336
337 manager->removeInvalidFaces(buffer);
338
339 // Run scheduler
340 nfd::tests::LimitedIo limitedIo;
341 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
342
343 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
344
345 Rib::const_iterator it = manager->m_managedRib.find("/test");
346 BOOST_REQUIRE(it != manager->m_managedRib.end());
347
348 shared_ptr<RibEntry> entry = it->second;
349 BOOST_CHECK_EQUAL(entry->hasFaceId(1), true);
350 BOOST_CHECK_EQUAL(entry->hasFaceId(2), false);
351}
352
Vince Lehman7c7d33a2015-01-20 17:40:26 -0600353BOOST_FIXTURE_TEST_CASE(LocalHopInherit, AuthorizedRibManager)
354{
355 using nfd::rib::RibManager;
356
357 // Simulate NFD response
358 ControlParameters result;
359 result.setFaceId(261);
360
361 manager->onNrdCommandPrefixAddNextHopSuccess(RibManager::REMOTE_COMMAND_PREFIX, result);
362
363 // Register route that localhop prefix should inherit
364 ControlParameters parameters;
365 parameters
366 .setName("/localhop/nfd")
367 .setFaceId(262)
368 .setCost(25)
369 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
370
371 Name commandName("/localhost/nfd/rib/register");
372
373 receiveCommandInterest(commandName, parameters);
374
375 // REMOTE_COMMAND_PREFIX should have its original route and the inherited route
376 auto it = manager->m_managedRib.find(RibManager::REMOTE_COMMAND_PREFIX);
377
378 BOOST_REQUIRE(it != manager->m_managedRib.end());
379 const RibEntry::RouteList& inheritedRoutes = (*(it->second)).getInheritedRoutes();
380
381 BOOST_CHECK_EQUAL(inheritedRoutes.size(), 1);
382 auto routeIt = inheritedRoutes.begin();
383
384 BOOST_CHECK_EQUAL(routeIt->faceId, 262);
385 BOOST_CHECK_EQUAL(routeIt->cost, 25);
386}
387
Vince Lehman76c751c2014-11-18 17:36:38 -0600388BOOST_FIXTURE_TEST_CASE(RouteExpiration, AuthorizedRibManager)
389{
390 // Register route
391 ControlParameters parameters;
392 parameters.setName("/expire")
393 .setExpirationPeriod(ndn::time::milliseconds(500));
394
395 receiveCommandInterest(REGISTER_COMMAND, parameters);
396 face->sentInterests.clear();
397
398 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
399
400 // Route should expire
401 nfd::tests::LimitedIo limitedIo;
402 limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
403
404 BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
405}
406
407BOOST_FIXTURE_TEST_CASE(FaceDestroyEvent, AuthorizedRibManager)
408{
409 uint64_t faceToDestroy = 128;
410
411 // Register valid face
412 ControlParameters parameters;
413 parameters.setName("/test")
414 .setFaceId(faceToDestroy);
415
416 receiveCommandInterest(REGISTER_COMMAND, parameters);
417 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
418
419 // Don't respond with a success message from the FIB
420 manager->m_managedRib.m_onSendBatchFromQueue = nullptr;
421
422 manager->onFaceDestroyedEvent(faceToDestroy);
423 BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 0);
424}
425
Vince Lehman72446ec2014-07-09 10:50:02 -0500426BOOST_AUTO_TEST_SUITE_END()
427
428} // namespace tests
429} // namespace rib
430} // namespace nfd