blob: 9905f8a40a79c891f58d10dfc0e64dd693690c11 [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>());
HangZhangad4afd12014-03-01 11:03:08 +0800169 NameTree nameTree(1024);
170 Fib fib(nameTree);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700171 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700172 bind(&FibManagerFixture::getFace, this, _1),
173 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700174
175 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700176
177 face->onReceiveData +=
178 bind(&FibManagerFixture::validateControlResponse, this, _1,
179 command.getName(), 400, "Malformed command");
180
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700181 face->sendInterest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700182
183 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700184}
185
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700186BOOST_AUTO_TEST_CASE(MalformedCommmand)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700187{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700188 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800189 NameTree nameTree(1024);
190 Fib fib(nameTree);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700191 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);
194
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700195 BOOST_REQUIRE(didCallbackFire() == false);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700196
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700197 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700198
199 face->onReceiveData +=
200 bind(&FibManagerFixture::validateControlResponse, this, _1,
201 command.getName(), 400, "Malformed command");
202
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700203 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700204
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700205 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700206}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700207
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700208BOOST_AUTO_TEST_CASE(UnsupportedVerb)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700209{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700210 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800211 NameTree nameTree(1024);
212 Fib fib(nameTree);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700213 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700214 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700215 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700216
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800217 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700218 options.setName("/hello");
219 options.setFaceId(1);
220 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700221
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700222 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700223
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700224 Name commandName("/localhost/nfd/fib");
225 commandName.append("unsupported");
226 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700227
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700228 face->onReceiveData +=
229 bind(&FibManagerFixture::validateControlResponse, this, _1,
230 commandName, 501, "Unsupported command");
231
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700232 Interest command(commandName);
233 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700234
235 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700236}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700237
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700238BOOST_AUTO_TEST_CASE(UnsignedCommand)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700239{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700240 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700241
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700242 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800243 NameTree nameTree(1024);
244 Fib fib(nameTree);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700245 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
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700273BOOST_AUTO_TEST_CASE(UnauthorizedCommand)
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>());
HangZhangad4afd12014-03-01 11:03:08 +0800278 NameTree nameTree(1024);
279 Fib fib(nameTree);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700280 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700281 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700282 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700283
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800284 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700285 options.setName("/hello");
286 options.setFaceId(1);
287 options.setCost(101);
288
289 Block encodedOptions(options.wireEncode());
290
291 Name commandName("/localhost/nfd/fib");
292 commandName.append("add-nexthop");
293 commandName.append(encodedOptions);
294
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700295 face->onReceiveData +=
296 bind(&FibManagerFixture::validateControlResponse, this, _1,
297 commandName, 404, "Prefix not found");
298 /// \todo enable once sig checking implemented
299 // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
300
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700301 Interest command(commandName);
302 manager.onFibRequest(command);
303
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700304 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700305 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700306}
307
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700308BOOST_AUTO_TEST_CASE(BadOptionParse)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700309{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700310 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700311
312 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800313 NameTree nameTree(1024);
314 Fib fib(nameTree);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700315 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);
318
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700319 Name commandName("/localhost/nfd/fib");
320 commandName.append("add-nexthop");
321 commandName.append("NotReallyOptions");
322
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700323 face->onReceiveData +=
324 bind(&FibManagerFixture::validateControlResponse, this, _1,
325 commandName, 400, "Malformed command");
326
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700327 Interest command(commandName);
328 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700329
330 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700331}
332
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700333BOOST_AUTO_TEST_CASE(UnknownFaceId)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700334{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700335 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700336
337 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800338 NameTree nameTree(1024);
339 Fib fib(nameTree);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700340 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700341 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700342 face);
343
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800344 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700345 options.setName("/hello");
346 options.setFaceId(1000);
347 options.setCost(101);
348
349 Block encodedOptions(options.wireEncode());
350
351 Name commandName("/localhost/nfd/fib");
352 commandName.append("add-nexthop");
353 commandName.append(encodedOptions);
354
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700355 face->onReceiveData +=
356 bind(&FibManagerFixture::validateControlResponse, this, _1,
357 commandName, 404, "Face not found");
358
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700359 Interest command(commandName);
360 manager.onFibRequest(command);
361
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700362 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700363 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
364}
365
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700366BOOST_AUTO_TEST_CASE(TestImplicitFaceId)
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700367{
368 addFace(make_shared<DummyFace>());
369
370 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800371 NameTree nameTree(1024);
372 Fib fib(nameTree);
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700373 FibManager manager(fib,
374 bind(&FibManagerFixture::getFace, this, _1),
375 face);
376
377 FibManagementOptions options;
378 options.setName("/hello");
379 options.setFaceId(0);
380 options.setCost(101);
381
382 Block encodedOptions(options.wireEncode());
383
384 Name commandName("/localhost/nfd/fib");
385 commandName.append("add-nexthop");
386 commandName.append(encodedOptions);
387
388 FibManagementOptions expectedOptions;
389 expectedOptions.setName("/hello");
390 expectedOptions.setFaceId(1);
391 expectedOptions.setCost(101);
392
393 Block encodedExpectedOptions(expectedOptions.wireEncode());
394
395 face->onReceiveData +=
396 bind(&FibManagerFixture::validateControlResponse, this, _1,
397 commandName, 200, "Success", encodedExpectedOptions);
398
399 fib.insert("/hello");
400
401 Interest command(commandName);
402 command.setIncomingFaceId(1);
403 manager.onFibRequest(command);
404
405 BOOST_REQUIRE(didCallbackFire());
406 BOOST_REQUIRE(addedNextHopWithFace(fib, "/hello", 0, 101, getFace(1)));
407}
408
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700409BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700410{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700411 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700412
413 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800414 NameTree nameTree(1024);
415 Fib fib(nameTree);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700416 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700417 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700418 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700419
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800420 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700421 options.setName("/hello");
422 options.setFaceId(1);
423 options.setCost(101);
424
425 Block encodedOptions(options.wireEncode());
426
427 Name commandName("/localhost/nfd/fib");
428 commandName.append("add-nexthop");
429 commandName.append(encodedOptions);
430
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700431 face->onReceiveData +=
432 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700433 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700434
435 fib.insert("/hello");
436
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700437 Interest command(commandName);
438 manager.onFibRequest(command);
439
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700440 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700441 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700442}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700443
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700444BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700445{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700446 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700447
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700448 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800449 NameTree nameTree(1024);
450 Fib fib(nameTree);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700451 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700452 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700453 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700454
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700455 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700456
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700457 for (int i = 1; i <= 2; i++)
458 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700459
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800460 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700461 options.setName("/hello");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700462 options.setFaceId(1);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700463 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700464
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700465 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700466
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700467 Name commandName("/localhost/nfd/fib");
468 commandName.append("add-nexthop");
469 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700470
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700471 face->onReceiveData +=
472 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700473 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700474
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700475 Interest command(commandName);
476 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700477 BOOST_REQUIRE(didCallbackFire());
478 resetCallbackFired();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700479
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700480 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700481
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700482 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700483 {
484 const fib::NextHopList& hops = entry->getNextHops();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700485 BOOST_REQUIRE(hops.size() == 1);
486 BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
487 bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
488
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700489 }
490 else
491 {
492 BOOST_FAIL("Failed to find expected fib entry");
493 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700494
495 face->onReceiveData.clear();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700496 }
497}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700498
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700499BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700500{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700501 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700502
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700503 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800504 NameTree nameTree(1024);
505 Fib fib(nameTree);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700506 FibManager manager(fib,
507 bind(&FibManagerFixture::getFace,
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700508 this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700509 face);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700510
511 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700512
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800513 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700514 options.setName("/hello");
515 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700516
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700517 {
518 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700519
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700520 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700521
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700522 Name commandName("/localhost/nfd/fib");
523 commandName.append("add-nexthop");
524 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700525
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700526 face->onReceiveData +=
527 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700528 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700529
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700530 Interest command(commandName);
531 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700532
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700533 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700534 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700535
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700536 resetCallbackFired();
537 face->onReceiveData.clear();
538
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700539 {
540 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700541
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700542 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700543
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700544 Name commandName("/localhost/nfd/fib");
545 commandName.append("add-nexthop");
546 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700547
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700548 face->onReceiveData +=
549 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700550 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700551
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700552 Interest command(commandName);
553 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700554
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700555 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700556 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700557
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700558 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700559
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700560 // Add faces with cost == FaceID for the name /hello
561 // This test assumes:
562 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700563 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700564 {
565 const fib::NextHopList& hops = entry->getNextHops();
566 BOOST_REQUIRE(hops.size() == 1);
567 BOOST_REQUIRE(std::find_if(hops.begin(),
568 hops.end(),
569 bind(&foundNextHop, -1, 102, _1)) != hops.end());
570 }
571 else
572 {
573 BOOST_FAIL("Failed to find expected fib entry");
574 }
575}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700576
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700577BOOST_AUTO_TEST_CASE(Insert)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700578{
579 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800580 NameTree nameTree(1024);
581 Fib fib(nameTree);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700582 FibManager manager(fib,
583 bind(&FibManagerFixture::getFace, this, _1),
584 face);
585
586 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800587 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700588 options.setName("/hello");
589
590 Block encodedOptions(options.wireEncode());
591
592 Name commandName("/localhost/nfd/fib");
593 commandName.append("insert");
594 commandName.append(encodedOptions);
595
596 face->onReceiveData +=
597 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700598 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700599
600 Interest command(commandName);
601 manager.onFibRequest(command);
602 }
603
604 BOOST_REQUIRE(didCallbackFire());
605
606 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
607 if (static_cast<bool>(entry))
608 {
609 const fib::NextHopList& hops = entry->getNextHops();
610 BOOST_CHECK_EQUAL(hops.size(), 0);
611 }
612
613 resetCallbackFired();
614
615 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800616 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700617 options.setName("/hello");
618
619 Block encodedOptions(options.wireEncode());
620
621 Name commandName("/localhost/nfd/fib");
622 commandName.append("insert");
623 commandName.append(encodedOptions);
624
625 face->onReceiveData +=
626 bind(&FibManagerFixture::validateControlResponse, this, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700627 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700628
629 Interest command(commandName);
630 manager.onFibRequest(command);
631 }
632
633 BOOST_REQUIRE(didCallbackFire());
634
635 entry = fib.findExactMatch("/hello");
636 if (static_cast<bool>(entry))
637 {
638 const fib::NextHopList& hops = entry->getNextHops();
639 BOOST_CHECK_EQUAL(hops.size(), 0);
640 }
641
642}
643
644void
645testRemove(FibManagerFixture* fixture,
646 FibManager& manager,
647 Fib& fib,
648 shared_ptr<Face> face,
649 const Name& target)
650{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800651 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700652 options.setName(target);
653
654 Block encodedOptions(options.wireEncode());
655
656 Name commandName("/localhost/nfd/fib");
657 commandName.append("delete");
658 commandName.append(encodedOptions);
659
660 face->onReceiveData +=
661 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700662 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700663
664 Interest command(commandName);
665 manager.onFibRequest(command);
666
667 BOOST_REQUIRE(fixture->didCallbackFire());
668
669 if (static_cast<bool>(fib.findExactMatch(target)))
670 {
671 BOOST_FAIL("Found \"removed\" prefix");
672 }
673 face->onReceiveData.clear();
674}
675
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700676BOOST_AUTO_TEST_CASE(Delete)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700677{
678 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800679 NameTree nameTree(1024);
680 Fib fib(nameTree);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700681 FibManager manager(fib,
682 bind(&FibManagerFixture::getFace, this, _1),
683 face);
684
685 fib.insert("/a");
686 fib.insert("/a/b");
687 fib.insert("/a/b/c");
688
689 testRemove(this, manager, fib, face, "/");
690
691 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
692 !static_cast<bool>(fib.findExactMatch("/a/b")) ||
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");
699
700 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
701 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
702 {
703 BOOST_FAIL("Removed incorrect entry");
704 }
705
706 testRemove(this, manager, fib, face, "/a/b/c");
707
708 if (!static_cast<bool>(fib.findExactMatch("/a")))
709 {
710 BOOST_FAIL("Removed incorrect entry");
711 }
712
713 testRemove(this, manager, fib, face, "/a");
714
715 testRemove(this, manager, fib, face, "/does/not/exist");
716}
717
718bool
719removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
720{
721 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
722
723 if (static_cast<bool>(entry))
724 {
725 const fib::NextHopList& hops = entry->getNextHops();
726 return hops.size() == oldSize - 1 &&
727 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
728 }
729 return false;
730}
731
732void
733testRemoveNextHop(FibManagerFixture* fixture,
734 FibManager& manager,
735 Fib& fib,
736 shared_ptr<Face> face,
737 const Name& targetName,
738 FaceId targetFace)
739{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800740 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700741 options.setName(targetName);
742 options.setFaceId(targetFace);
743
744 Block encodedOptions(options.wireEncode());
745
746 Name commandName("/localhost/nfd/fib");
747 commandName.append("remove-nexthop");
748 commandName.append(encodedOptions);
749
750 face->onReceiveData +=
751 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
Steve DiBenedetto2693db92014-02-10 15:58:36 -0700752 commandName, 200, "Success", encodedOptions);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700753
754 Interest command(commandName);
755 manager.onFibRequest(command);
756
757 BOOST_REQUIRE(fixture->didCallbackFire());
758
759 fixture->resetCallbackFired();
760 face->onReceiveData.clear();
761}
762
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700763BOOST_AUTO_TEST_CASE(RemoveNextHop)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700764{
765 shared_ptr<Face> face1 = make_shared<DummyFace>();
766 shared_ptr<Face> face2 = make_shared<DummyFace>();
767 shared_ptr<Face> face3 = make_shared<DummyFace>();
768
769 addFace(face1);
770 addFace(face2);
771 addFace(face3);
772
773 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800774 NameTree nameTree(1024);
775 Fib fib(nameTree);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700776 FibManager manager(fib,
777 bind(&FibManagerFixture::getFace, this, _1),
778 face);
779
780 shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
781
782 entry->addNextHop(face1, 101);
783 entry->addNextHop(face2, 202);
784 entry->addNextHop(face3, 303);
785
786 testRemoveNextHop(this, manager, fib, face, "/hello", 2);
787 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
788
789 testRemoveNextHop(this, manager, fib, face, "/hello", 3);
790 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
791
792 testRemoveNextHop(this, manager, fib, face, "/hello", 1);
793 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
794
795 if (!static_cast<bool>(fib.findExactMatch("/hello")))
796 {
797 BOOST_FAIL("removed entry after removing all next hops");
798 }
799
800}
801
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700802BOOST_AUTO_TEST_CASE(RemoveNoFace)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700803{
804 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800805 NameTree nameTree(1024);
806 Fib fib(nameTree);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700807 FibManager manager(fib,
808 bind(&FibManagerFixture::getFace, this, _1),
809 face);
810
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800811 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700812 options.setName("/hello");
813 options.setFaceId(1);
814
815 Block encodedOptions(options.wireEncode());
816
817 Name commandName("/localhost/nfd/fib");
818 commandName.append("remove-nexthop");
819 commandName.append(encodedOptions);
820
821 face->onReceiveData +=
822 bind(&FibManagerFixture::validateControlResponse, this, _1,
823 commandName, 404, "Face not found");
824
825 Interest command(commandName);
826 manager.onFibRequest(command);
827
828 BOOST_REQUIRE(didCallbackFire());
829}
830
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700831BOOST_AUTO_TEST_CASE(RemoveNoPrefix)
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700832{
833 addFace(make_shared<DummyFace>());
834
835 shared_ptr<InternalFace> face(make_shared<InternalFace>());
HangZhangad4afd12014-03-01 11:03:08 +0800836 NameTree nameTree(1024);
837 Fib fib(nameTree);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700838 FibManager manager(fib,
839 bind(&FibManagerFixture::getFace, this, _1),
840 face);
841
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800842 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700843 options.setName("/hello");
844 options.setFaceId(1);
845
846 Block encodedOptions(options.wireEncode());
847
848 Name commandName("/localhost/nfd/fib");
849 commandName.append("remove-nexthop");
850 commandName.append(encodedOptions);
851
852 face->onReceiveData +=
853 bind(&FibManagerFixture::validateControlResponse, this, _1,
854 commandName, 404, "Prefix not found");
855
856 Interest command(commandName);
857 manager.onFibRequest(command);
858
859 BOOST_REQUIRE(didCallbackFire());
860}
861
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700862BOOST_AUTO_TEST_SUITE_END()
863
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700864} // namespace tests
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700865} // namespace nfd