blob: 25c38b382cf76d4108b5bf628978e771acf9b9d3 [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 <ndn-cpp-dev/management/fib-management-options.hpp>
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070017#include <ndn-cpp-dev/management/control-response.hpp>
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070018
19#include <boost/test/unit_test.hpp>
20
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070021namespace nfd {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070022
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070023NFD_LOG_INIT("FibManagerTest");
24
25class FibManagerFixture
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070026{
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070027public:
28
Steve DiBenedettobdedce92014-02-02 22:49:39 -070029 FibManagerFixture()
30 : m_callbackFired(false)
31 {
32
33 }
34
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070035 shared_ptr<Face>
36 getFace(FaceId id)
37 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070038 if (id > 0 && id <= m_faces.size())
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070039 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070040 return m_faces[id-1];
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070041 }
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070042 NFD_LOG_DEBUG("No face found returning NULL");
43 return shared_ptr<DummyFace>();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070044 }
45
46 void
47 addFace(shared_ptr<Face> face)
48 {
49 m_faces.push_back(face);
50 }
51
Steve DiBenedettobdedce92014-02-02 22:49:39 -070052 void
53 validateControlResponse(const Data& response,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070054 const Name& expectedName,
Steve DiBenedettobdedce92014-02-02 22:49:39 -070055 uint32_t expectedCode,
56 const std::string& expectedText)
57 {
58 m_callbackFired = true;
59 Block controlRaw = response.getContent().blockFromValue();
60
61 ndn::ControlResponse control;
62 control.wireDecode(controlRaw);
63
64 NFD_LOG_DEBUG("received control response"
65 << " Name: " << response.getName()
66 << " code: " << control.getCode()
67 << " text: " << control.getText());
68
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070069 BOOST_CHECK_EQUAL(response.getName(), expectedName);
70 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
71 BOOST_CHECK_EQUAL(control.getText(), expectedText);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070072 }
73
74 bool
75 didCallbackFire()
76 {
77 return m_callbackFired;
78 }
79
80 void
81 resetCallbackFired()
82 {
83 m_callbackFired = false;
84 }
85
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070086private:
87 std::vector<shared_ptr<Face> > m_faces;
Steve DiBenedettobdedce92014-02-02 22:49:39 -070088 bool m_callbackFired;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070089};
90
91
92BOOST_AUTO_TEST_SUITE(MgmtFibManager)
93
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070094
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070095
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070096bool
97foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
98{
99 return id == next.getFace()->getId() && next.getCost() == cost;
100}
101
102bool
103addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
104{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700105 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700106
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700107 if (static_cast<bool>(entry))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700108 {
109 const fib::NextHopList& hops = entry->getNextHops();
110 return hops.size() == oldSize + 1 &&
111 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
112 }
113 return false;
114}
115
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700116BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700117{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700118 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700119 Fib fib;
120 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700121 bind(&FibManagerFixture::getFace, this, _1),
122 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700123
124 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700125
126 face->onReceiveData +=
127 bind(&FibManagerFixture::validateControlResponse, this, _1,
128 command.getName(), 400, "Malformed command");
129
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700130 face->sendInterest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700131
132 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700133}
134
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700135BOOST_FIXTURE_TEST_CASE(MalformedCommmand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700136{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700137 shared_ptr<InternalFace> face(make_shared<InternalFace>());
138 Fib fib;
139 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700140 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700141 face);
142
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700143 BOOST_REQUIRE(didCallbackFire() == false);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700144
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700145 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700146
147 face->onReceiveData +=
148 bind(&FibManagerFixture::validateControlResponse, this, _1,
149 command.getName(), 400, "Malformed command");
150
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700151 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700152
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700153 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700154}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700155
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700156BOOST_FIXTURE_TEST_CASE(UnsupportedVerb, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700157{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700158 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700159 Fib fib;
160 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700161 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700162 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700163
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700164 ndn::FibManagementOptions options;
165 options.setName("/hello");
166 options.setFaceId(1);
167 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700168
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700169 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700170
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700171 Name commandName("/localhost/nfd/fib");
172 commandName.append("unsupported");
173 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700174
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700175 face->onReceiveData +=
176 bind(&FibManagerFixture::validateControlResponse, this, _1,
177 commandName, 501, "Unsupported command");
178
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700179 Interest command(commandName);
180 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700181
182 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700183}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700184
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700185BOOST_FIXTURE_TEST_CASE(UnsignedCommand, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700186{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700187 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700188
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700189 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700190 Fib fib;
191 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700192 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700193 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700194
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700195 ndn::FibManagementOptions options;
196 options.setName("/hello");
197 options.setFaceId(1);
198 options.setCost(101);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700199
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700200 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700201
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700202 Name commandName("/localhost/nfd/fib");
203 commandName.append("add-nexthop");
204 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700205
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700206 face->onReceiveData +=
207 bind(&FibManagerFixture::validateControlResponse, this, _1,
208 commandName, 404, "Prefix not found");
209 /// \todo enable once sig checking implemented
210 // bind(&FibManagerFixture::validateControlResponse, this, _1, 401, "Signature required");
211
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700212 Interest command(commandName);
213 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700214
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700215 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700216 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700217}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700218
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700219BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700220{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700221 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700222
223 shared_ptr<InternalFace> face(make_shared<InternalFace>());
224 Fib fib;
225 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700226 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700227 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700228
229 ndn::FibManagementOptions options;
230 options.setName("/hello");
231 options.setFaceId(1);
232 options.setCost(101);
233
234 Block encodedOptions(options.wireEncode());
235
236 Name commandName("/localhost/nfd/fib");
237 commandName.append("add-nexthop");
238 commandName.append(encodedOptions);
239
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700240 face->onReceiveData +=
241 bind(&FibManagerFixture::validateControlResponse, this, _1,
242 commandName, 404, "Prefix not found");
243 /// \todo enable once sig checking implemented
244 // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
245
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700246 Interest command(commandName);
247 manager.onFibRequest(command);
248
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700249 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700250 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700251}
252
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700253BOOST_FIXTURE_TEST_CASE(BadOptionParse, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700254{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700255 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700256
257 shared_ptr<InternalFace> face(make_shared<InternalFace>());
258 Fib fib;
259 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700260 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700261 face);
262
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700263 Name commandName("/localhost/nfd/fib");
264 commandName.append("add-nexthop");
265 commandName.append("NotReallyOptions");
266
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700267 face->onReceiveData +=
268 bind(&FibManagerFixture::validateControlResponse, this, _1,
269 commandName, 400, "Malformed command");
270
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700271 Interest command(commandName);
272 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700273
274 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700275}
276
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700277BOOST_FIXTURE_TEST_CASE(UnknownFaceId, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700278{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700279 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700280
281 shared_ptr<InternalFace> face(make_shared<InternalFace>());
282 Fib fib;
283 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700284 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700285 face);
286
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700287 ndn::FibManagementOptions options;
288 options.setName("/hello");
289 options.setFaceId(1000);
290 options.setCost(101);
291
292 Block encodedOptions(options.wireEncode());
293
294 Name commandName("/localhost/nfd/fib");
295 commandName.append("add-nexthop");
296 commandName.append(encodedOptions);
297
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700298 face->onReceiveData +=
299 bind(&FibManagerFixture::validateControlResponse, this, _1,
300 commandName, 404, "Face not found");
301
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700302 Interest command(commandName);
303 manager.onFibRequest(command);
304
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700305 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700306 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
307}
308
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700309BOOST_FIXTURE_TEST_CASE(AddNextHopVerbInitialAdd, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700310{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700311 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700312
313 shared_ptr<InternalFace> face(make_shared<InternalFace>());
314 Fib fib;
315 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700316 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700317 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700318
319 ndn::FibManagementOptions options;
320 options.setName("/hello");
321 options.setFaceId(1);
322 options.setCost(101);
323
324 Block encodedOptions(options.wireEncode());
325
326 Name commandName("/localhost/nfd/fib");
327 commandName.append("add-nexthop");
328 commandName.append(encodedOptions);
329
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700330 face->onReceiveData +=
331 bind(&FibManagerFixture::validateControlResponse, this, _1,
332 commandName, 200, "OK");
333
334 fib.insert("/hello");
335
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700336 Interest command(commandName);
337 manager.onFibRequest(command);
338
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700339 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700340 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700341}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700342
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700343BOOST_FIXTURE_TEST_CASE(AddNextHopVerbAddToExisting, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700344{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700345 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700346
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700347 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700348 Fib fib;
349 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700350 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700351 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700352
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700353 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700354
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700355 for (int i = 1; i <= 2; i++)
356 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700357
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700358 ndn::FibManagementOptions options;
359 options.setName("/hello");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700360 options.setFaceId(1);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700361 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700362
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700363 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700364
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700365 Name commandName("/localhost/nfd/fib");
366 commandName.append("add-nexthop");
367 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700368
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700369 face->onReceiveData +=
370 bind(&FibManagerFixture::validateControlResponse, this, _1,
371 commandName, 200, "OK");
372
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700373 Interest command(commandName);
374 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700375 BOOST_REQUIRE(didCallbackFire());
376 resetCallbackFired();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700377
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700378 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700379
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700380 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700381 {
382 const fib::NextHopList& hops = entry->getNextHops();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700383 BOOST_REQUIRE(hops.size() == 1);
384 BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
385 bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
386
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700387 }
388 else
389 {
390 BOOST_FAIL("Failed to find expected fib entry");
391 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700392
393 face->onReceiveData.clear();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700394 }
395}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700396
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700397BOOST_FIXTURE_TEST_CASE(AddNextHopVerbUpdateFaceCost, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700398{
399 FibManagerFixture fixture;
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700400 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700401
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700402 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700403 Fib fib;
404 FibManager manager(fib,
405 bind(&FibManagerFixture::getFace,
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700406 this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700407 face);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700408
409 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700410
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700411 ndn::FibManagementOptions options;
412 options.setName("/hello");
413 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700414
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700415 {
416 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700417
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700418 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700419
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700420 Name commandName("/localhost/nfd/fib");
421 commandName.append("add-nexthop");
422 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700423
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700424 face->onReceiveData +=
425 bind(&FibManagerFixture::validateControlResponse, this, _1,
426 commandName, 200, "OK");
427
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700428 Interest command(commandName);
429 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700430
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700431 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700432 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700433
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700434 resetCallbackFired();
435 face->onReceiveData.clear();
436
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700437 {
438 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700439
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700440 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700441
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700442 Name commandName("/localhost/nfd/fib");
443 commandName.append("add-nexthop");
444 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700445
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700446 face->onReceiveData +=
447 bind(&FibManagerFixture::validateControlResponse, this, _1,
448 commandName, 200, "OK");
449
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700450 Interest command(commandName);
451 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700452
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700453 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700454 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700455
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700456 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700457
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700458 // Add faces with cost == FaceID for the name /hello
459 // This test assumes:
460 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700461 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700462 {
463 const fib::NextHopList& hops = entry->getNextHops();
464 BOOST_REQUIRE(hops.size() == 1);
465 BOOST_REQUIRE(std::find_if(hops.begin(),
466 hops.end(),
467 bind(&foundNextHop, -1, 102, _1)) != hops.end());
468 }
469 else
470 {
471 BOOST_FAIL("Failed to find expected fib entry");
472 }
473}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700474
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700475BOOST_FIXTURE_TEST_CASE(Insert, FibManagerFixture)
476{
477 shared_ptr<InternalFace> face(make_shared<InternalFace>());
478 Fib fib;
479 FibManager manager(fib,
480 bind(&FibManagerFixture::getFace, this, _1),
481 face);
482
483 {
484 ndn::FibManagementOptions options;
485 options.setName("/hello");
486
487 Block encodedOptions(options.wireEncode());
488
489 Name commandName("/localhost/nfd/fib");
490 commandName.append("insert");
491 commandName.append(encodedOptions);
492
493 face->onReceiveData +=
494 bind(&FibManagerFixture::validateControlResponse, this, _1,
495 commandName, 200, "OK");
496
497 Interest command(commandName);
498 manager.onFibRequest(command);
499 }
500
501 BOOST_REQUIRE(didCallbackFire());
502
503 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
504 if (static_cast<bool>(entry))
505 {
506 const fib::NextHopList& hops = entry->getNextHops();
507 BOOST_CHECK_EQUAL(hops.size(), 0);
508 }
509
510 resetCallbackFired();
511
512 {
513 ndn::FibManagementOptions options;
514 options.setName("/hello");
515
516 Block encodedOptions(options.wireEncode());
517
518 Name commandName("/localhost/nfd/fib");
519 commandName.append("insert");
520 commandName.append(encodedOptions);
521
522 face->onReceiveData +=
523 bind(&FibManagerFixture::validateControlResponse, this, _1,
524 commandName, 200, "OK");
525
526 Interest command(commandName);
527 manager.onFibRequest(command);
528 }
529
530 BOOST_REQUIRE(didCallbackFire());
531
532 entry = fib.findExactMatch("/hello");
533 if (static_cast<bool>(entry))
534 {
535 const fib::NextHopList& hops = entry->getNextHops();
536 BOOST_CHECK_EQUAL(hops.size(), 0);
537 }
538
539}
540
541void
542testRemove(FibManagerFixture* fixture,
543 FibManager& manager,
544 Fib& fib,
545 shared_ptr<Face> face,
546 const Name& target)
547{
548 ndn::FibManagementOptions options;
549 options.setName(target);
550
551 Block encodedOptions(options.wireEncode());
552
553 Name commandName("/localhost/nfd/fib");
554 commandName.append("delete");
555 commandName.append(encodedOptions);
556
557 face->onReceiveData +=
558 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
559 commandName, 200, "OK");
560
561 Interest command(commandName);
562 manager.onFibRequest(command);
563
564 BOOST_REQUIRE(fixture->didCallbackFire());
565
566 if (static_cast<bool>(fib.findExactMatch(target)))
567 {
568 BOOST_FAIL("Found \"removed\" prefix");
569 }
570 face->onReceiveData.clear();
571}
572
573BOOST_FIXTURE_TEST_CASE(Delete, FibManagerFixture)
574{
575 shared_ptr<InternalFace> face(make_shared<InternalFace>());
576 Fib fib;
577 FibManager manager(fib,
578 bind(&FibManagerFixture::getFace, this, _1),
579 face);
580
581 fib.insert("/a");
582 fib.insert("/a/b");
583 fib.insert("/a/b/c");
584
585 testRemove(this, manager, fib, face, "/");
586
587 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
588 !static_cast<bool>(fib.findExactMatch("/a/b")) ||
589 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
590 {
591 BOOST_FAIL("Removed incorrect entry");
592 }
593
594 testRemove(this, manager, fib, face, "/a/b");
595
596 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
597 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
598 {
599 BOOST_FAIL("Removed incorrect entry");
600 }
601
602 testRemove(this, manager, fib, face, "/a/b/c");
603
604 if (!static_cast<bool>(fib.findExactMatch("/a")))
605 {
606 BOOST_FAIL("Removed incorrect entry");
607 }
608
609 testRemove(this, manager, fib, face, "/a");
610
611 testRemove(this, manager, fib, face, "/does/not/exist");
612}
613
614bool
615removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
616{
617 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
618
619 if (static_cast<bool>(entry))
620 {
621 const fib::NextHopList& hops = entry->getNextHops();
622 return hops.size() == oldSize - 1 &&
623 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
624 }
625 return false;
626}
627
628void
629testRemoveNextHop(FibManagerFixture* fixture,
630 FibManager& manager,
631 Fib& fib,
632 shared_ptr<Face> face,
633 const Name& targetName,
634 FaceId targetFace)
635{
636 ndn::FibManagementOptions options;
637 options.setName(targetName);
638 options.setFaceId(targetFace);
639
640 Block encodedOptions(options.wireEncode());
641
642 Name commandName("/localhost/nfd/fib");
643 commandName.append("remove-nexthop");
644 commandName.append(encodedOptions);
645
646 face->onReceiveData +=
647 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
648 commandName, 200, "OK");
649
650 Interest command(commandName);
651 manager.onFibRequest(command);
652
653 BOOST_REQUIRE(fixture->didCallbackFire());
654
655 fixture->resetCallbackFired();
656 face->onReceiveData.clear();
657}
658
659BOOST_FIXTURE_TEST_CASE(RemoveNextHop, FibManagerFixture)
660{
661 shared_ptr<Face> face1 = make_shared<DummyFace>();
662 shared_ptr<Face> face2 = make_shared<DummyFace>();
663 shared_ptr<Face> face3 = make_shared<DummyFace>();
664
665 addFace(face1);
666 addFace(face2);
667 addFace(face3);
668
669 shared_ptr<InternalFace> face(make_shared<InternalFace>());
670 Fib fib;
671 FibManager manager(fib,
672 bind(&FibManagerFixture::getFace, this, _1),
673 face);
674
675 shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
676
677 entry->addNextHop(face1, 101);
678 entry->addNextHop(face2, 202);
679 entry->addNextHop(face3, 303);
680
681 testRemoveNextHop(this, manager, fib, face, "/hello", 2);
682 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
683
684 testRemoveNextHop(this, manager, fib, face, "/hello", 3);
685 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
686
687 testRemoveNextHop(this, manager, fib, face, "/hello", 1);
688 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
689
690 if (!static_cast<bool>(fib.findExactMatch("/hello")))
691 {
692 BOOST_FAIL("removed entry after removing all next hops");
693 }
694
695}
696
697BOOST_FIXTURE_TEST_CASE(RemoveNoFace, FibManagerFixture)
698{
699 shared_ptr<InternalFace> face(make_shared<InternalFace>());
700 Fib fib;
701 FibManager manager(fib,
702 bind(&FibManagerFixture::getFace, this, _1),
703 face);
704
705 ndn::FibManagementOptions options;
706 options.setName("/hello");
707 options.setFaceId(1);
708
709 Block encodedOptions(options.wireEncode());
710
711 Name commandName("/localhost/nfd/fib");
712 commandName.append("remove-nexthop");
713 commandName.append(encodedOptions);
714
715 face->onReceiveData +=
716 bind(&FibManagerFixture::validateControlResponse, this, _1,
717 commandName, 404, "Face not found");
718
719 Interest command(commandName);
720 manager.onFibRequest(command);
721
722 BOOST_REQUIRE(didCallbackFire());
723}
724
725BOOST_FIXTURE_TEST_CASE(RemoveNoPrefix, FibManagerFixture)
726{
727 addFace(make_shared<DummyFace>());
728
729 shared_ptr<InternalFace> face(make_shared<InternalFace>());
730 Fib fib;
731 FibManager manager(fib,
732 bind(&FibManagerFixture::getFace, this, _1),
733 face);
734
735 ndn::FibManagementOptions options;
736 options.setName("/hello");
737 options.setFaceId(1);
738
739 Block encodedOptions(options.wireEncode());
740
741 Name commandName("/localhost/nfd/fib");
742 commandName.append("remove-nexthop");
743 commandName.append(encodedOptions);
744
745 face->onReceiveData +=
746 bind(&FibManagerFixture::validateControlResponse, this, _1,
747 commandName, 404, "Prefix not found");
748
749 Interest command(commandName);
750 manager.onFibRequest(command);
751
752 BOOST_REQUIRE(didCallbackFire());
753}
754
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700755BOOST_AUTO_TEST_SUITE_END()
756
757} // namespace nfd