blob: 2352f53923abf99f1d6efbed0e188afd89706d4a [file] [log] [blame]
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "mgmt/fib-manager.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07008#include "table/fib.hpp"
Steve DiBenedetto43cd0372014-02-01 17:05:07 -07009#include "table/fib-nexthop.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070010#include "face/face.hpp"
Steve DiBenedetto3970c892014-01-31 23:31:13 -070011#include "mgmt/internal-face.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070012#include "../face/dummy-face.hpp"
13
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070014#include <algorithm>
15
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070016#include <boost/test/unit_test.hpp>
17
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070018namespace nfd {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070019
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070020NFD_LOG_INIT("FibManagerTest");
21
22class FibManagerFixture
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070023{
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070024public:
25
Steve DiBenedettobdedce92014-02-02 22:49:39 -070026 FibManagerFixture()
27 : m_callbackFired(false)
28 {
29
30 }
31
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070032 shared_ptr<Face>
33 getFace(FaceId id)
34 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070035 if (id > 0 && id <= m_faces.size())
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070036 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070037 return m_faces[id-1];
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070038 }
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070039 NFD_LOG_DEBUG("No face found returning NULL");
40 return shared_ptr<DummyFace>();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070041 }
42
43 void
44 addFace(shared_ptr<Face> face)
45 {
46 m_faces.push_back(face);
47 }
48
Steve DiBenedettobdedce92014-02-02 22:49:39 -070049 void
Steve DiBenedetto2693db92014-02-10 15:58:36 -070050 validateControlResponseCommon(const Data& response,
51 const Name& expectedName,
52 uint32_t expectedCode,
53 const std::string& expectedText,
54 ControlResponse& control)
Steve DiBenedettobdedce92014-02-02 22:49:39 -070055 {
56 m_callbackFired = true;
57 Block controlRaw = response.getContent().blockFromValue();
58
Steve DiBenedettobdedce92014-02-02 22:49:39 -070059 control.wireDecode(controlRaw);
60
61 NFD_LOG_DEBUG("received control response"
62 << " Name: " << response.getName()
63 << " code: " << control.getCode()
64 << " text: " << control.getText());
65
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070066 BOOST_CHECK_EQUAL(response.getName(), expectedName);
67 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
68 BOOST_CHECK_EQUAL(control.getText(), expectedText);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070069 }
70
Steve DiBenedetto2693db92014-02-10 15:58:36 -070071 void
72 validateControlResponse(const Data& response,
73 const Name& expectedName,
74 uint32_t expectedCode,
75 const std::string& expectedText)
76 {
77 ControlResponse control;
78 validateControlResponseCommon(response, expectedName,
79 expectedCode, expectedText, control);
80
81 if (!control.getBody().empty())
82 {
83 BOOST_FAIL("found unexpected control response body");
84 }
85 }
86
87 void
88 validateControlResponse(const Data& response,
89 const Name& expectedName,
90 uint32_t expectedCode,
91 const std::string& expectedText,
92 const Block& expectedBody)
93 {
94 ControlResponse control;
95 validateControlResponseCommon(response, expectedName,
96 expectedCode, expectedText, control);
97
98 BOOST_REQUIRE(!control.getBody().empty());
99 BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
100
101 BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
102 expectedBody.value_size()) == 0);
103
104 }
105
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700106 bool
107 didCallbackFire()
108 {
109 return m_callbackFired;
110 }
111
112 void
113 resetCallbackFired()
114 {
115 m_callbackFired = false;
116 }
117
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700118private:
119 std::vector<shared_ptr<Face> > m_faces;
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700120 bool m_callbackFired;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700121};
122
123
124BOOST_AUTO_TEST_SUITE(MgmtFibManager)
125
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700126
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700127
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700128bool
129foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
130{
131 return id == next.getFace()->getId() && next.getCost() == cost;
132}
133
134bool
135addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
136{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700137 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700138
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700139 if (static_cast<bool>(entry))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700140 {
141 const fib::NextHopList& hops = entry->getNextHops();
142 return hops.size() == oldSize + 1 &&
143 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
144 }
145 return false;
146}
147
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700148bool
149foundNextHopWithFace(FaceId id, uint32_t cost,
150 shared_ptr<Face> face, const fib::NextHop& next)
151{
152 return id == next.getFace()->getId() && next.getCost() == cost && face == next.getFace();
153}
154
155bool
156addedNextHopWithFace(const Fib& fib, const Name& prefix, size_t oldSize,
157 uint32_t cost, shared_ptr<Face> face)
158{
159 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
160
161 if (static_cast<bool>(entry))
162 {
163 const fib::NextHopList& hops = entry->getNextHops();
164 return hops.size() == oldSize + 1 &&
165 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
166 }
167 return false;
168}
169
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700170BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700171{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700172 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700173 Fib fib;
174 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700175 bind(&FibManagerFixture::getFace, this, _1),
176 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700177
178 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700179
180 face->onReceiveData +=
181 bind(&FibManagerFixture::validateControlResponse, this, _1,
182 command.getName(), 400, "Malformed command");
183
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700184 face->sendInterest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700185
186 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700187}
188
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700189BOOST_FIXTURE_TEST_CASE(MalformedCommmand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700190{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700191 shared_ptr<InternalFace> face(make_shared<InternalFace>());
192 Fib fib;
193 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700194 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700195 face);
196
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700197 BOOST_REQUIRE(didCallbackFire() == false);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700198
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700199 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700200
201 face->onReceiveData +=
202 bind(&FibManagerFixture::validateControlResponse, this, _1,
203 command.getName(), 400, "Malformed command");
204
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700205 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700206
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700207 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700208}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700209
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700210BOOST_FIXTURE_TEST_CASE(UnsupportedVerb, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700211{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700212 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700213 Fib fib;
214 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700215 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700216 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700217
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800218 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700219 options.setName("/hello");
220 options.setFaceId(1);
221 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700222
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700223 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700225 Name commandName("/localhost/nfd/fib");
226 commandName.append("unsupported");
227 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700228
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700229 face->onReceiveData +=
230 bind(&FibManagerFixture::validateControlResponse, this, _1,
231 commandName, 501, "Unsupported command");
232
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700233 Interest command(commandName);
234 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700235
236 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700237}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700238
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700239BOOST_FIXTURE_TEST_CASE(UnsignedCommand, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700240{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700241 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700242
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700243 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700244 Fib fib;
245 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700246 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700247 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700248
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800249 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700250 options.setName("/hello");
251 options.setFaceId(1);
252 options.setCost(101);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700253
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700254 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700255
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700256 Name commandName("/localhost/nfd/fib");
257 commandName.append("add-nexthop");
258 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700259
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700260 face->onReceiveData +=
261 bind(&FibManagerFixture::validateControlResponse, this, _1,
262 commandName, 404, "Prefix not found");
263 /// \todo enable once sig checking implemented
264 // bind(&FibManagerFixture::validateControlResponse, this, _1, 401, "Signature required");
265
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700266 Interest command(commandName);
267 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700268
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700269 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700270 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700271}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700272
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700273BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700274{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700275 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700276
277 shared_ptr<InternalFace> face(make_shared<InternalFace>());
278 Fib fib;
279 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700280 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700281 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700282
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800283 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700284 options.setName("/hello");
285 options.setFaceId(1);
286 options.setCost(101);
287
288 Block encodedOptions(options.wireEncode());
289
290 Name commandName("/localhost/nfd/fib");
291 commandName.append("add-nexthop");
292 commandName.append(encodedOptions);
293
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700294 face->onReceiveData +=
295 bind(&FibManagerFixture::validateControlResponse, this, _1,
296 commandName, 404, "Prefix not found");
297 /// \todo enable once sig checking implemented
298 // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
299
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700300 Interest command(commandName);
301 manager.onFibRequest(command);
302
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700303 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700304 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700305}
306
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700307BOOST_FIXTURE_TEST_CASE(BadOptionParse, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700308{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700309 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700310
311 shared_ptr<InternalFace> face(make_shared<InternalFace>());
312 Fib fib;
313 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700314 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700315 face);
316
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700317 Name commandName("/localhost/nfd/fib");
318 commandName.append("add-nexthop");
319 commandName.append("NotReallyOptions");
320
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700321 face->onReceiveData +=
322 bind(&FibManagerFixture::validateControlResponse, this, _1,
323 commandName, 400, "Malformed command");
324
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700325 Interest command(commandName);
326 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700327
328 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700329}
330
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700331BOOST_FIXTURE_TEST_CASE(UnknownFaceId, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700332{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700333 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700334
335 shared_ptr<InternalFace> face(make_shared<InternalFace>());
336 Fib fib;
337 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700338 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700339 face);
340
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800341 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700342 options.setName("/hello");
343 options.setFaceId(1000);
344 options.setCost(101);
345
346 Block encodedOptions(options.wireEncode());
347
348 Name commandName("/localhost/nfd/fib");
349 commandName.append("add-nexthop");
350 commandName.append(encodedOptions);
351
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700352 face->onReceiveData +=
353 bind(&FibManagerFixture::validateControlResponse, this, _1,
354 commandName, 404, "Face not found");
355
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700356 Interest command(commandName);
357 manager.onFibRequest(command);
358
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700359 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700360 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
361}
362
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700363BOOST_FIXTURE_TEST_CASE(TestImplicitFaceId, FibManagerFixture)
364{
365 addFace(make_shared<DummyFace>());
366
367 shared_ptr<InternalFace> face(make_shared<InternalFace>());
368 Fib fib;
369 FibManager manager(fib,
370 bind(&FibManagerFixture::getFace, this, _1),
371 face);
372
373 FibManagementOptions options;
374 options.setName("/hello");
375 options.setFaceId(0);
376 options.setCost(101);
377
378 Block encodedOptions(options.wireEncode());
379
380 Name commandName("/localhost/nfd/fib");
381 commandName.append("add-nexthop");
382 commandName.append(encodedOptions);
383
384 FibManagementOptions expectedOptions;
385 expectedOptions.setName("/hello");
386 expectedOptions.setFaceId(1);
387 expectedOptions.setCost(101);
388
389 Block encodedExpectedOptions(expectedOptions.wireEncode());
390
391 face->onReceiveData +=
392 bind(&FibManagerFixture::validateControlResponse, this, _1,
393 commandName, 200, "Success", encodedExpectedOptions);
394
395 fib.insert("/hello");
396
397 Interest command(commandName);
398 command.setIncomingFaceId(1);
399 manager.onFibRequest(command);
400
401 BOOST_REQUIRE(didCallbackFire());
402 BOOST_REQUIRE(addedNextHopWithFace(fib, "/hello", 0, 101, getFace(1)));
403}
404
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700405BOOST_FIXTURE_TEST_CASE(AddNextHopVerbInitialAdd, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700406{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700407 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700408
409 shared_ptr<InternalFace> face(make_shared<InternalFace>());
410 Fib fib;
411 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700412 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700413 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700414
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800415 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700416 options.setName("/hello");
417 options.setFaceId(1);
418 options.setCost(101);
419
420 Block encodedOptions(options.wireEncode());
421
422 Name commandName("/localhost/nfd/fib");
423 commandName.append("add-nexthop");
424 commandName.append(encodedOptions);
425
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700426 face->onReceiveData +=
427 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700428 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700429
430 fib.insert("/hello");
431
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700432 Interest command(commandName);
433 manager.onFibRequest(command);
434
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700435 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700436 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700437}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700438
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700439BOOST_FIXTURE_TEST_CASE(AddNextHopVerbAddToExisting, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700440{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700441 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700442
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700443 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700444 Fib fib;
445 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700446 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700447 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700448
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700449 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700450
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700451 for (int i = 1; i <= 2; i++)
452 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700453
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800454 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700455 options.setName("/hello");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700456 options.setFaceId(1);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700457 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700458
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700459 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700460
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700461 Name commandName("/localhost/nfd/fib");
462 commandName.append("add-nexthop");
463 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700464
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700465 face->onReceiveData +=
466 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700467 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700468
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700469 Interest command(commandName);
470 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700471 BOOST_REQUIRE(didCallbackFire());
472 resetCallbackFired();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700473
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700474 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700475
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700476 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700477 {
478 const fib::NextHopList& hops = entry->getNextHops();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700479 BOOST_REQUIRE(hops.size() == 1);
480 BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
481 bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
482
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700483 }
484 else
485 {
486 BOOST_FAIL("Failed to find expected fib entry");
487 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700488
489 face->onReceiveData.clear();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700490 }
491}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700492
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700493BOOST_FIXTURE_TEST_CASE(AddNextHopVerbUpdateFaceCost, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700494{
495 FibManagerFixture fixture;
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700496 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700497
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700498 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700499 Fib fib;
500 FibManager manager(fib,
501 bind(&FibManagerFixture::getFace,
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700502 this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700503 face);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700504
505 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700506
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800507 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700508 options.setName("/hello");
509 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700510
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700511 {
512 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700513
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700514 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700515
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700516 Name commandName("/localhost/nfd/fib");
517 commandName.append("add-nexthop");
518 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700519
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700520 face->onReceiveData +=
521 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700522 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700523
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700524 Interest command(commandName);
525 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700526
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700527 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700528 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700529
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700530 resetCallbackFired();
531 face->onReceiveData.clear();
532
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700533 {
534 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700535
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700536 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700537
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700538 Name commandName("/localhost/nfd/fib");
539 commandName.append("add-nexthop");
540 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700541
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700542 face->onReceiveData +=
543 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700544 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700545
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700546 Interest command(commandName);
547 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700548
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700549 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700550 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700551
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700552 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700553
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700554 // Add faces with cost == FaceID for the name /hello
555 // This test assumes:
556 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700557 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700558 {
559 const fib::NextHopList& hops = entry->getNextHops();
560 BOOST_REQUIRE(hops.size() == 1);
561 BOOST_REQUIRE(std::find_if(hops.begin(),
562 hops.end(),
563 bind(&foundNextHop, -1, 102, _1)) != hops.end());
564 }
565 else
566 {
567 BOOST_FAIL("Failed to find expected fib entry");
568 }
569}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700570
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700571BOOST_FIXTURE_TEST_CASE(Insert, FibManagerFixture)
572{
573 shared_ptr<InternalFace> face(make_shared<InternalFace>());
574 Fib fib;
575 FibManager manager(fib,
576 bind(&FibManagerFixture::getFace, this, _1),
577 face);
578
579 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800580 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700581 options.setName("/hello");
582
583 Block encodedOptions(options.wireEncode());
584
585 Name commandName("/localhost/nfd/fib");
586 commandName.append("insert");
587 commandName.append(encodedOptions);
588
589 face->onReceiveData +=
590 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700591 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700592
593 Interest command(commandName);
594 manager.onFibRequest(command);
595 }
596
597 BOOST_REQUIRE(didCallbackFire());
598
599 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
600 if (static_cast<bool>(entry))
601 {
602 const fib::NextHopList& hops = entry->getNextHops();
603 BOOST_CHECK_EQUAL(hops.size(), 0);
604 }
605
606 resetCallbackFired();
607
608 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800609 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700610 options.setName("/hello");
611
612 Block encodedOptions(options.wireEncode());
613
614 Name commandName("/localhost/nfd/fib");
615 commandName.append("insert");
616 commandName.append(encodedOptions);
617
618 face->onReceiveData +=
619 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700620 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700621
622 Interest command(commandName);
623 manager.onFibRequest(command);
624 }
625
626 BOOST_REQUIRE(didCallbackFire());
627
628 entry = fib.findExactMatch("/hello");
629 if (static_cast<bool>(entry))
630 {
631 const fib::NextHopList& hops = entry->getNextHops();
632 BOOST_CHECK_EQUAL(hops.size(), 0);
633 }
634
635}
636
637void
638testRemove(FibManagerFixture* fixture,
639 FibManager& manager,
640 Fib& fib,
641 shared_ptr<Face> face,
642 const Name& target)
643{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800644 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700645 options.setName(target);
646
647 Block encodedOptions(options.wireEncode());
648
649 Name commandName("/localhost/nfd/fib");
650 commandName.append("delete");
651 commandName.append(encodedOptions);
652
653 face->onReceiveData +=
654 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700655 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700656
657 Interest command(commandName);
658 manager.onFibRequest(command);
659
660 BOOST_REQUIRE(fixture->didCallbackFire());
661
662 if (static_cast<bool>(fib.findExactMatch(target)))
663 {
664 BOOST_FAIL("Found \"removed\" prefix");
665 }
666 face->onReceiveData.clear();
667}
668
669BOOST_FIXTURE_TEST_CASE(Delete, FibManagerFixture)
670{
671 shared_ptr<InternalFace> face(make_shared<InternalFace>());
672 Fib fib;
673 FibManager manager(fib,
674 bind(&FibManagerFixture::getFace, this, _1),
675 face);
676
677 fib.insert("/a");
678 fib.insert("/a/b");
679 fib.insert("/a/b/c");
680
681 testRemove(this, manager, fib, face, "/");
682
683 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
684 !static_cast<bool>(fib.findExactMatch("/a/b")) ||
685 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
686 {
687 BOOST_FAIL("Removed incorrect entry");
688 }
689
690 testRemove(this, manager, fib, face, "/a/b");
691
692 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
693 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
694 {
695 BOOST_FAIL("Removed incorrect entry");
696 }
697
698 testRemove(this, manager, fib, face, "/a/b/c");
699
700 if (!static_cast<bool>(fib.findExactMatch("/a")))
701 {
702 BOOST_FAIL("Removed incorrect entry");
703 }
704
705 testRemove(this, manager, fib, face, "/a");
706
707 testRemove(this, manager, fib, face, "/does/not/exist");
708}
709
710bool
711removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
712{
713 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
714
715 if (static_cast<bool>(entry))
716 {
717 const fib::NextHopList& hops = entry->getNextHops();
718 return hops.size() == oldSize - 1 &&
719 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
720 }
721 return false;
722}
723
724void
725testRemoveNextHop(FibManagerFixture* fixture,
726 FibManager& manager,
727 Fib& fib,
728 shared_ptr<Face> face,
729 const Name& targetName,
730 FaceId targetFace)
731{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800732 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700733 options.setName(targetName);
734 options.setFaceId(targetFace);
735
736 Block encodedOptions(options.wireEncode());
737
738 Name commandName("/localhost/nfd/fib");
739 commandName.append("remove-nexthop");
740 commandName.append(encodedOptions);
741
742 face->onReceiveData +=
743 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700744 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700745
746 Interest command(commandName);
747 manager.onFibRequest(command);
748
749 BOOST_REQUIRE(fixture->didCallbackFire());
750
751 fixture->resetCallbackFired();
752 face->onReceiveData.clear();
753}
754
755BOOST_FIXTURE_TEST_CASE(RemoveNextHop, FibManagerFixture)
756{
757 shared_ptr<Face> face1 = make_shared<DummyFace>();
758 shared_ptr<Face> face2 = make_shared<DummyFace>();
759 shared_ptr<Face> face3 = make_shared<DummyFace>();
760
761 addFace(face1);
762 addFace(face2);
763 addFace(face3);
764
765 shared_ptr<InternalFace> face(make_shared<InternalFace>());
766 Fib fib;
767 FibManager manager(fib,
768 bind(&FibManagerFixture::getFace, this, _1),
769 face);
770
771 shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
772
773 entry->addNextHop(face1, 101);
774 entry->addNextHop(face2, 202);
775 entry->addNextHop(face3, 303);
776
777 testRemoveNextHop(this, manager, fib, face, "/hello", 2);
778 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
779
780 testRemoveNextHop(this, manager, fib, face, "/hello", 3);
781 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
782
783 testRemoveNextHop(this, manager, fib, face, "/hello", 1);
784 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
785
786 if (!static_cast<bool>(fib.findExactMatch("/hello")))
787 {
788 BOOST_FAIL("removed entry after removing all next hops");
789 }
790
791}
792
793BOOST_FIXTURE_TEST_CASE(RemoveNoFace, FibManagerFixture)
794{
795 shared_ptr<InternalFace> face(make_shared<InternalFace>());
796 Fib fib;
797 FibManager manager(fib,
798 bind(&FibManagerFixture::getFace, this, _1),
799 face);
800
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800801 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700802 options.setName("/hello");
803 options.setFaceId(1);
804
805 Block encodedOptions(options.wireEncode());
806
807 Name commandName("/localhost/nfd/fib");
808 commandName.append("remove-nexthop");
809 commandName.append(encodedOptions);
810
811 face->onReceiveData +=
812 bind(&FibManagerFixture::validateControlResponse, this, _1,
813 commandName, 404, "Face not found");
814
815 Interest command(commandName);
816 manager.onFibRequest(command);
817
818 BOOST_REQUIRE(didCallbackFire());
819}
820
821BOOST_FIXTURE_TEST_CASE(RemoveNoPrefix, FibManagerFixture)
822{
823 addFace(make_shared<DummyFace>());
824
825 shared_ptr<InternalFace> face(make_shared<InternalFace>());
826 Fib fib;
827 FibManager manager(fib,
828 bind(&FibManagerFixture::getFace, this, _1),
829 face);
830
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800831 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700832 options.setName("/hello");
833 options.setFaceId(1);
834
835 Block encodedOptions(options.wireEncode());
836
837 Name commandName("/localhost/nfd/fib");
838 commandName.append("remove-nexthop");
839 commandName.append(encodedOptions);
840
841 face->onReceiveData +=
842 bind(&FibManagerFixture::validateControlResponse, this, _1,
843 commandName, 404, "Prefix not found");
844
845 Interest command(commandName);
846 manager.onFibRequest(command);
847
848 BOOST_REQUIRE(didCallbackFire());
849}
850
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700851BOOST_AUTO_TEST_SUITE_END()
852
853} // namespace nfd