blob: 00043d276c48fa49458554359ecbe4a29c37fc43 [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"
Junxiao Shid9ee45c2014-02-27 15:38:11 -070012#include "tests/face/dummy-face.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070013
Junxiao Shid9ee45c2014-02-27 15:38:11 -070014#include "tests/test-common.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070015
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070016namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070017namespace tests {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070018
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070019NFD_LOG_INIT("FibManagerTest");
20
Junxiao Shid9ee45c2014-02-27 15:38:11 -070021class FibManagerFixture : protected BaseFixture
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070022{
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070023public:
24
Steve DiBenedettobdedce92014-02-02 22:49:39 -070025 FibManagerFixture()
26 : m_callbackFired(false)
27 {
28
29 }
30
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070031 shared_ptr<Face>
32 getFace(FaceId id)
33 {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070034 if (id > 0 && static_cast<size_t>(id) <= m_faces.size())
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070035 {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070036 return m_faces[id - 1];
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070037 }
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070038 NFD_LOG_DEBUG("No face found returning NULL");
39 return shared_ptr<DummyFace>();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070040 }
41
42 void
43 addFace(shared_ptr<Face> face)
44 {
45 m_faces.push_back(face);
46 }
47
Steve DiBenedettobdedce92014-02-02 22:49:39 -070048 void
Steve DiBenedetto2693db92014-02-10 15:58:36 -070049 validateControlResponseCommon(const Data& response,
50 const Name& expectedName,
51 uint32_t expectedCode,
52 const std::string& expectedText,
53 ControlResponse& control)
Steve DiBenedettobdedce92014-02-02 22:49:39 -070054 {
55 m_callbackFired = true;
56 Block controlRaw = response.getContent().blockFromValue();
57
Steve DiBenedettobdedce92014-02-02 22:49:39 -070058 control.wireDecode(controlRaw);
59
60 NFD_LOG_DEBUG("received control response"
61 << " Name: " << response.getName()
62 << " code: " << control.getCode()
63 << " text: " << control.getText());
64
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070065 BOOST_CHECK_EQUAL(response.getName(), expectedName);
66 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
67 BOOST_CHECK_EQUAL(control.getText(), expectedText);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070068 }
69
Steve DiBenedetto2693db92014-02-10 15:58:36 -070070 void
71 validateControlResponse(const Data& response,
72 const Name& expectedName,
73 uint32_t expectedCode,
74 const std::string& expectedText)
75 {
76 ControlResponse control;
77 validateControlResponseCommon(response, expectedName,
78 expectedCode, expectedText, control);
79
80 if (!control.getBody().empty())
81 {
82 BOOST_FAIL("found unexpected control response body");
83 }
84 }
85
86 void
87 validateControlResponse(const Data& response,
88 const Name& expectedName,
89 uint32_t expectedCode,
90 const std::string& expectedText,
91 const Block& expectedBody)
92 {
93 ControlResponse control;
94 validateControlResponseCommon(response, expectedName,
95 expectedCode, expectedText, control);
96
97 BOOST_REQUIRE(!control.getBody().empty());
98 BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
99
100 BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
101 expectedBody.value_size()) == 0);
102
103 }
104
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700105 bool
106 didCallbackFire()
107 {
108 return m_callbackFired;
109 }
110
111 void
112 resetCallbackFired()
113 {
114 m_callbackFired = false;
115 }
116
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700117private:
118 std::vector<shared_ptr<Face> > m_faces;
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700119 bool m_callbackFired;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700120};
121
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700122BOOST_FIXTURE_TEST_SUITE(MgmtFibManager, FibManagerFixture)
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700123
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700124bool
125foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
126{
127 return id == next.getFace()->getId() && next.getCost() == cost;
128}
129
130bool
131addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
132{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700133 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700134
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700135 if (static_cast<bool>(entry))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700136 {
137 const fib::NextHopList& hops = entry->getNextHops();
138 return hops.size() == oldSize + 1 &&
139 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
140 }
141 return false;
142}
143
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700144bool
145foundNextHopWithFace(FaceId id, uint32_t cost,
146 shared_ptr<Face> face, const fib::NextHop& next)
147{
148 return id == next.getFace()->getId() && next.getCost() == cost && face == next.getFace();
149}
150
151bool
152addedNextHopWithFace(const Fib& fib, const Name& prefix, size_t oldSize,
153 uint32_t cost, shared_ptr<Face> face)
154{
155 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
156
157 if (static_cast<bool>(entry))
158 {
159 const fib::NextHopList& hops = entry->getNextHops();
160 return hops.size() == oldSize + 1 &&
161 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
162 }
163 return false;
164}
165
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700166BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700167{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700168 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700169 Fib fib;
170 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700171 bind(&FibManagerFixture::getFace, this, _1),
172 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700173
174 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700175
176 face->onReceiveData +=
177 bind(&FibManagerFixture::validateControlResponse, this, _1,
178 command.getName(), 400, "Malformed command");
179
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700180 face->sendInterest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700181
182 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700183}
184
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700185BOOST_AUTO_TEST_CASE(MalformedCommmand)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700186{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700187 shared_ptr<InternalFace> face(make_shared<InternalFace>());
188 Fib fib;
189 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700190 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700191 face);
192
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700193 BOOST_REQUIRE(didCallbackFire() == false);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700194
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700195 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700196
197 face->onReceiveData +=
198 bind(&FibManagerFixture::validateControlResponse, this, _1,
199 command.getName(), 400, "Malformed command");
200
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700201 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700202
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700203 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700204}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700205
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700206BOOST_AUTO_TEST_CASE(UnsupportedVerb)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700207{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700208 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700209 Fib fib;
210 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700211 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700212 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700213
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800214 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700215 options.setName("/hello");
216 options.setFaceId(1);
217 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700218
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700219 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700220
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700221 Name commandName("/localhost/nfd/fib");
222 commandName.append("unsupported");
223 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700225 face->onReceiveData +=
226 bind(&FibManagerFixture::validateControlResponse, this, _1,
227 commandName, 501, "Unsupported command");
228
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700229 Interest command(commandName);
230 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700231
232 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700233}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700234
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700235BOOST_AUTO_TEST_CASE(UnsignedCommand)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700236{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700237 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700238
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700239 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700240 Fib fib;
241 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700242 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700243 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700244
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800245 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700246 options.setName("/hello");
247 options.setFaceId(1);
248 options.setCost(101);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700249
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700250 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700251
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700252 Name commandName("/localhost/nfd/fib");
253 commandName.append("add-nexthop");
254 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700255
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700256 face->onReceiveData +=
257 bind(&FibManagerFixture::validateControlResponse, this, _1,
258 commandName, 404, "Prefix not found");
259 /// \todo enable once sig checking implemented
260 // bind(&FibManagerFixture::validateControlResponse, this, _1, 401, "Signature required");
261
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700262 Interest command(commandName);
263 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700264
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700265 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700266 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700267}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700268
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700269BOOST_AUTO_TEST_CASE(UnauthorizedCommand)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700270{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700271 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700272
273 shared_ptr<InternalFace> face(make_shared<InternalFace>());
274 Fib fib;
275 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700276 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700277 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700278
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800279 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700280 options.setName("/hello");
281 options.setFaceId(1);
282 options.setCost(101);
283
284 Block encodedOptions(options.wireEncode());
285
286 Name commandName("/localhost/nfd/fib");
287 commandName.append("add-nexthop");
288 commandName.append(encodedOptions);
289
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700290 face->onReceiveData +=
291 bind(&FibManagerFixture::validateControlResponse, this, _1,
292 commandName, 404, "Prefix not found");
293 /// \todo enable once sig checking implemented
294 // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
295
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700296 Interest command(commandName);
297 manager.onFibRequest(command);
298
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700299 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700300 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700301}
302
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700303BOOST_AUTO_TEST_CASE(BadOptionParse)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700304{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700305 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700306
307 shared_ptr<InternalFace> face(make_shared<InternalFace>());
308 Fib fib;
309 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700310 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700311 face);
312
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700313 Name commandName("/localhost/nfd/fib");
314 commandName.append("add-nexthop");
315 commandName.append("NotReallyOptions");
316
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700317 face->onReceiveData +=
318 bind(&FibManagerFixture::validateControlResponse, this, _1,
319 commandName, 400, "Malformed command");
320
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700321 Interest command(commandName);
322 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700323
324 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700325}
326
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700327BOOST_AUTO_TEST_CASE(UnknownFaceId)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700328{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700329 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700330
331 shared_ptr<InternalFace> face(make_shared<InternalFace>());
332 Fib fib;
333 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700334 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700335 face);
336
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800337 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700338 options.setName("/hello");
339 options.setFaceId(1000);
340 options.setCost(101);
341
342 Block encodedOptions(options.wireEncode());
343
344 Name commandName("/localhost/nfd/fib");
345 commandName.append("add-nexthop");
346 commandName.append(encodedOptions);
347
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700348 face->onReceiveData +=
349 bind(&FibManagerFixture::validateControlResponse, this, _1,
350 commandName, 404, "Face not found");
351
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700352 Interest command(commandName);
353 manager.onFibRequest(command);
354
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700355 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700356 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
357}
358
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700359BOOST_AUTO_TEST_CASE(TestImplicitFaceId)
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700360{
361 addFace(make_shared<DummyFace>());
362
363 shared_ptr<InternalFace> face(make_shared<InternalFace>());
364 Fib fib;
365 FibManager manager(fib,
366 bind(&FibManagerFixture::getFace, this, _1),
367 face);
368
369 FibManagementOptions options;
370 options.setName("/hello");
371 options.setFaceId(0);
372 options.setCost(101);
373
374 Block encodedOptions(options.wireEncode());
375
376 Name commandName("/localhost/nfd/fib");
377 commandName.append("add-nexthop");
378 commandName.append(encodedOptions);
379
380 FibManagementOptions expectedOptions;
381 expectedOptions.setName("/hello");
382 expectedOptions.setFaceId(1);
383 expectedOptions.setCost(101);
384
385 Block encodedExpectedOptions(expectedOptions.wireEncode());
386
387 face->onReceiveData +=
388 bind(&FibManagerFixture::validateControlResponse, this, _1,
389 commandName, 200, "Success", encodedExpectedOptions);
390
391 fib.insert("/hello");
392
393 Interest command(commandName);
394 command.setIncomingFaceId(1);
395 manager.onFibRequest(command);
396
397 BOOST_REQUIRE(didCallbackFire());
398 BOOST_REQUIRE(addedNextHopWithFace(fib, "/hello", 0, 101, getFace(1)));
399}
400
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700401BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700402{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700403 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700404
405 shared_ptr<InternalFace> face(make_shared<InternalFace>());
406 Fib fib;
407 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700408 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700409 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700410
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800411 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700412 options.setName("/hello");
413 options.setFaceId(1);
414 options.setCost(101);
415
416 Block encodedOptions(options.wireEncode());
417
418 Name commandName("/localhost/nfd/fib");
419 commandName.append("add-nexthop");
420 commandName.append(encodedOptions);
421
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700422 face->onReceiveData +=
423 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700424 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700425
426 fib.insert("/hello");
427
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700428 Interest command(commandName);
429 manager.onFibRequest(command);
430
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700431 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700432 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700433}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700434
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700435BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700436{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700437 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700438
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700439 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700440 Fib fib;
441 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700442 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700443 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700444
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700445 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700446
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700447 for (int i = 1; i <= 2; i++)
448 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700449
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800450 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700451 options.setName("/hello");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700452 options.setFaceId(1);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700453 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700454
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700455 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700456
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700457 Name commandName("/localhost/nfd/fib");
458 commandName.append("add-nexthop");
459 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700460
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700461 face->onReceiveData +=
462 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700463 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700464
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700465 Interest command(commandName);
466 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700467 BOOST_REQUIRE(didCallbackFire());
468 resetCallbackFired();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700469
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700470 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700471
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700472 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700473 {
474 const fib::NextHopList& hops = entry->getNextHops();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700475 BOOST_REQUIRE(hops.size() == 1);
476 BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
477 bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
478
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700479 }
480 else
481 {
482 BOOST_FAIL("Failed to find expected fib entry");
483 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700484
485 face->onReceiveData.clear();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700486 }
487}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700488
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700489BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700490{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700491 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700492
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700493 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700494 Fib fib;
495 FibManager manager(fib,
496 bind(&FibManagerFixture::getFace,
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700497 this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700498 face);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700499
500 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700501
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800502 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700503 options.setName("/hello");
504 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700505
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700506 {
507 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700508
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700509 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700510
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700511 Name commandName("/localhost/nfd/fib");
512 commandName.append("add-nexthop");
513 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700514
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700515 face->onReceiveData +=
516 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700517 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700518
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700519 Interest command(commandName);
520 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700521
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700522 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700523 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700524
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700525 resetCallbackFired();
526 face->onReceiveData.clear();
527
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700528 {
529 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700530
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700531 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700532
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700533 Name commandName("/localhost/nfd/fib");
534 commandName.append("add-nexthop");
535 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700536
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700537 face->onReceiveData +=
538 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700539 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700540
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700541 Interest command(commandName);
542 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700543
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700544 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700545 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700546
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700547 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700548
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700549 // Add faces with cost == FaceID for the name /hello
550 // This test assumes:
551 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700552 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700553 {
554 const fib::NextHopList& hops = entry->getNextHops();
555 BOOST_REQUIRE(hops.size() == 1);
556 BOOST_REQUIRE(std::find_if(hops.begin(),
557 hops.end(),
558 bind(&foundNextHop, -1, 102, _1)) != hops.end());
559 }
560 else
561 {
562 BOOST_FAIL("Failed to find expected fib entry");
563 }
564}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700565
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700566BOOST_AUTO_TEST_CASE(Insert)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700567{
568 shared_ptr<InternalFace> face(make_shared<InternalFace>());
569 Fib fib;
570 FibManager manager(fib,
571 bind(&FibManagerFixture::getFace, this, _1),
572 face);
573
574 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800575 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700576 options.setName("/hello");
577
578 Block encodedOptions(options.wireEncode());
579
580 Name commandName("/localhost/nfd/fib");
581 commandName.append("insert");
582 commandName.append(encodedOptions);
583
584 face->onReceiveData +=
585 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700586 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700587
588 Interest command(commandName);
589 manager.onFibRequest(command);
590 }
591
592 BOOST_REQUIRE(didCallbackFire());
593
594 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
595 if (static_cast<bool>(entry))
596 {
597 const fib::NextHopList& hops = entry->getNextHops();
598 BOOST_CHECK_EQUAL(hops.size(), 0);
599 }
600
601 resetCallbackFired();
602
603 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800604 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700605 options.setName("/hello");
606
607 Block encodedOptions(options.wireEncode());
608
609 Name commandName("/localhost/nfd/fib");
610 commandName.append("insert");
611 commandName.append(encodedOptions);
612
613 face->onReceiveData +=
614 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700615 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700616
617 Interest command(commandName);
618 manager.onFibRequest(command);
619 }
620
621 BOOST_REQUIRE(didCallbackFire());
622
623 entry = fib.findExactMatch("/hello");
624 if (static_cast<bool>(entry))
625 {
626 const fib::NextHopList& hops = entry->getNextHops();
627 BOOST_CHECK_EQUAL(hops.size(), 0);
628 }
629
630}
631
632void
633testRemove(FibManagerFixture* fixture,
634 FibManager& manager,
635 Fib& fib,
636 shared_ptr<Face> face,
637 const Name& target)
638{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800639 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700640 options.setName(target);
641
642 Block encodedOptions(options.wireEncode());
643
644 Name commandName("/localhost/nfd/fib");
645 commandName.append("delete");
646 commandName.append(encodedOptions);
647
648 face->onReceiveData +=
649 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700650 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700651
652 Interest command(commandName);
653 manager.onFibRequest(command);
654
655 BOOST_REQUIRE(fixture->didCallbackFire());
656
657 if (static_cast<bool>(fib.findExactMatch(target)))
658 {
659 BOOST_FAIL("Found \"removed\" prefix");
660 }
661 face->onReceiveData.clear();
662}
663
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700664BOOST_AUTO_TEST_CASE(Delete)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700665{
666 shared_ptr<InternalFace> face(make_shared<InternalFace>());
667 Fib fib;
668 FibManager manager(fib,
669 bind(&FibManagerFixture::getFace, this, _1),
670 face);
671
672 fib.insert("/a");
673 fib.insert("/a/b");
674 fib.insert("/a/b/c");
675
676 testRemove(this, manager, fib, face, "/");
677
678 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
679 !static_cast<bool>(fib.findExactMatch("/a/b")) ||
680 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
681 {
682 BOOST_FAIL("Removed incorrect entry");
683 }
684
685 testRemove(this, manager, fib, face, "/a/b");
686
687 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
688 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
689 {
690 BOOST_FAIL("Removed incorrect entry");
691 }
692
693 testRemove(this, manager, fib, face, "/a/b/c");
694
695 if (!static_cast<bool>(fib.findExactMatch("/a")))
696 {
697 BOOST_FAIL("Removed incorrect entry");
698 }
699
700 testRemove(this, manager, fib, face, "/a");
701
702 testRemove(this, manager, fib, face, "/does/not/exist");
703}
704
705bool
706removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
707{
708 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
709
710 if (static_cast<bool>(entry))
711 {
712 const fib::NextHopList& hops = entry->getNextHops();
713 return hops.size() == oldSize - 1 &&
714 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
715 }
716 return false;
717}
718
719void
720testRemoveNextHop(FibManagerFixture* fixture,
721 FibManager& manager,
722 Fib& fib,
723 shared_ptr<Face> face,
724 const Name& targetName,
725 FaceId targetFace)
726{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800727 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700728 options.setName(targetName);
729 options.setFaceId(targetFace);
730
731 Block encodedOptions(options.wireEncode());
732
733 Name commandName("/localhost/nfd/fib");
734 commandName.append("remove-nexthop");
735 commandName.append(encodedOptions);
736
737 face->onReceiveData +=
738 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700739 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700740
741 Interest command(commandName);
742 manager.onFibRequest(command);
743
744 BOOST_REQUIRE(fixture->didCallbackFire());
745
746 fixture->resetCallbackFired();
747 face->onReceiveData.clear();
748}
749
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700750BOOST_AUTO_TEST_CASE(RemoveNextHop)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700751{
752 shared_ptr<Face> face1 = make_shared<DummyFace>();
753 shared_ptr<Face> face2 = make_shared<DummyFace>();
754 shared_ptr<Face> face3 = make_shared<DummyFace>();
755
756 addFace(face1);
757 addFace(face2);
758 addFace(face3);
759
760 shared_ptr<InternalFace> face(make_shared<InternalFace>());
761 Fib fib;
762 FibManager manager(fib,
763 bind(&FibManagerFixture::getFace, this, _1),
764 face);
765
766 shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
767
768 entry->addNextHop(face1, 101);
769 entry->addNextHop(face2, 202);
770 entry->addNextHop(face3, 303);
771
772 testRemoveNextHop(this, manager, fib, face, "/hello", 2);
773 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
774
775 testRemoveNextHop(this, manager, fib, face, "/hello", 3);
776 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
777
778 testRemoveNextHop(this, manager, fib, face, "/hello", 1);
779 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
780
781 if (!static_cast<bool>(fib.findExactMatch("/hello")))
782 {
783 BOOST_FAIL("removed entry after removing all next hops");
784 }
785
786}
787
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700788BOOST_AUTO_TEST_CASE(RemoveNoFace)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700789{
790 shared_ptr<InternalFace> face(make_shared<InternalFace>());
791 Fib fib;
792 FibManager manager(fib,
793 bind(&FibManagerFixture::getFace, this, _1),
794 face);
795
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800796 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700797 options.setName("/hello");
798 options.setFaceId(1);
799
800 Block encodedOptions(options.wireEncode());
801
802 Name commandName("/localhost/nfd/fib");
803 commandName.append("remove-nexthop");
804 commandName.append(encodedOptions);
805
806 face->onReceiveData +=
807 bind(&FibManagerFixture::validateControlResponse, this, _1,
808 commandName, 404, "Face not found");
809
810 Interest command(commandName);
811 manager.onFibRequest(command);
812
813 BOOST_REQUIRE(didCallbackFire());
814}
815
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700816BOOST_AUTO_TEST_CASE(RemoveNoPrefix)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700817{
818 addFace(make_shared<DummyFace>());
819
820 shared_ptr<InternalFace> face(make_shared<InternalFace>());
821 Fib fib;
822 FibManager manager(fib,
823 bind(&FibManagerFixture::getFace, this, _1),
824 face);
825
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800826 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700827 options.setName("/hello");
828 options.setFaceId(1);
829
830 Block encodedOptions(options.wireEncode());
831
832 Name commandName("/localhost/nfd/fib");
833 commandName.append("remove-nexthop");
834 commandName.append(encodedOptions);
835
836 face->onReceiveData +=
837 bind(&FibManagerFixture::validateControlResponse, this, _1,
838 commandName, 404, "Prefix not found");
839
840 Interest command(commandName);
841 manager.onFibRequest(command);
842
843 BOOST_REQUIRE(didCallbackFire());
844}
845
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700846BOOST_AUTO_TEST_SUITE_END()
847
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700848} // namespace tests
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700849} // namespace nfd