blob: 1c1cf9fbce384d9ba388a7d8dfc1068afa416425 [file] [log] [blame]
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "mgmt/fib-manager.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -07008#include "table/fib.hpp"
Steve DiBenedetto43cd0372014-02-01 17:05:07 -07009#include "table/fib-nexthop.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070010#include "face/face.hpp"
Steve DiBenedetto3970c892014-01-31 23:31:13 -070011#include "mgmt/internal-face.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070012#include "../face/dummy-face.hpp"
13
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070014#include <algorithm>
15
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070016#include <boost/test/unit_test.hpp>
17
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070018namespace nfd {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070019
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070020NFD_LOG_INIT("FibManagerTest");
21
22class FibManagerFixture
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070023{
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070024public:
25
Steve DiBenedettobdedce92014-02-02 22:49:39 -070026 FibManagerFixture()
27 : m_callbackFired(false)
28 {
29
30 }
31
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070032 shared_ptr<Face>
33 getFace(FaceId id)
34 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070035 if (id > 0 && id <= m_faces.size())
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070036 {
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070037 return m_faces[id-1];
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070038 }
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070039 NFD_LOG_DEBUG("No face found returning NULL");
40 return shared_ptr<DummyFace>();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070041 }
42
43 void
44 addFace(shared_ptr<Face> face)
45 {
46 m_faces.push_back(face);
47 }
48
Steve DiBenedettobdedce92014-02-02 22:49:39 -070049 void
50 validateControlResponse(const Data& response,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070051 const Name& expectedName,
Steve DiBenedettobdedce92014-02-02 22:49:39 -070052 uint32_t expectedCode,
53 const std::string& expectedText)
54 {
55 m_callbackFired = true;
56 Block controlRaw = response.getContent().blockFromValue();
57
Alexander Afanasyevd482fd32014-02-09 23:40:20 -080058 ControlResponse control;
Steve DiBenedettobdedce92014-02-02 22:49:39 -070059 control.wireDecode(controlRaw);
60
61 NFD_LOG_DEBUG("received control response"
62 << " Name: " << response.getName()
63 << " code: " << control.getCode()
64 << " text: " << control.getText());
65
Steve DiBenedetto0b73f442014-02-05 22:02:03 -070066 BOOST_CHECK_EQUAL(response.getName(), expectedName);
67 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
68 BOOST_CHECK_EQUAL(control.getText(), expectedText);
Steve DiBenedettobdedce92014-02-02 22:49:39 -070069 }
70
71 bool
72 didCallbackFire()
73 {
74 return m_callbackFired;
75 }
76
77 void
78 resetCallbackFired()
79 {
80 m_callbackFired = false;
81 }
82
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070083private:
84 std::vector<shared_ptr<Face> > m_faces;
Steve DiBenedettobdedce92014-02-02 22:49:39 -070085 bool m_callbackFired;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070086};
87
88
89BOOST_AUTO_TEST_SUITE(MgmtFibManager)
90
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070091
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070092
Steve DiBenedetto80ddc212014-02-01 22:23:56 -070093bool
94foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
95{
96 return id == next.getFace()->getId() && next.getCost() == cost;
97}
98
99bool
100addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
101{
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700102 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700103
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700104 if (static_cast<bool>(entry))
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700105 {
106 const fib::NextHopList& hops = entry->getNextHops();
107 return hops.size() == oldSize + 1 &&
108 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
109 }
110 return false;
111}
112
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700113BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700114{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700115 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700116 Fib fib;
117 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700118 bind(&FibManagerFixture::getFace, this, _1),
119 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700120
121 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700122
123 face->onReceiveData +=
124 bind(&FibManagerFixture::validateControlResponse, this, _1,
125 command.getName(), 400, "Malformed command");
126
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700127 face->sendInterest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700128
129 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700130}
131
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700132BOOST_FIXTURE_TEST_CASE(MalformedCommmand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700133{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700134 shared_ptr<InternalFace> face(make_shared<InternalFace>());
135 Fib fib;
136 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700137 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700138 face);
139
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700140 BOOST_REQUIRE(didCallbackFire() == false);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700141
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700142 Interest command("/localhost/nfd/fib");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700143
144 face->onReceiveData +=
145 bind(&FibManagerFixture::validateControlResponse, this, _1,
146 command.getName(), 400, "Malformed command");
147
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700148 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700149
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700150 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700151}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700152
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700153BOOST_FIXTURE_TEST_CASE(UnsupportedVerb, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700154{
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700155 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700156 Fib fib;
157 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700158 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700159 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700160
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800161 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700162 options.setName("/hello");
163 options.setFaceId(1);
164 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700165
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700166 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700167
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700168 Name commandName("/localhost/nfd/fib");
169 commandName.append("unsupported");
170 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700171
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700172 face->onReceiveData +=
173 bind(&FibManagerFixture::validateControlResponse, this, _1,
174 commandName, 501, "Unsupported command");
175
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700176 Interest command(commandName);
177 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700178
179 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700180}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700181
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700182BOOST_FIXTURE_TEST_CASE(UnsignedCommand, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700183{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700184 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700185
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700186 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700187 Fib fib;
188 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700189 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700190 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700191
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800192 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700193 options.setName("/hello");
194 options.setFaceId(1);
195 options.setCost(101);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700196
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700197 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700198
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700199 Name commandName("/localhost/nfd/fib");
200 commandName.append("add-nexthop");
201 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700202
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700203 face->onReceiveData +=
204 bind(&FibManagerFixture::validateControlResponse, this, _1,
205 commandName, 404, "Prefix not found");
206 /// \todo enable once sig checking implemented
207 // bind(&FibManagerFixture::validateControlResponse, this, _1, 401, "Signature required");
208
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700209 Interest command(commandName);
210 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700211
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700212 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700213 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700214}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700215
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700216BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700217{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700218 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700219
220 shared_ptr<InternalFace> face(make_shared<InternalFace>());
221 Fib fib;
222 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700223 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700224 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700225
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800226 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700227 options.setName("/hello");
228 options.setFaceId(1);
229 options.setCost(101);
230
231 Block encodedOptions(options.wireEncode());
232
233 Name commandName("/localhost/nfd/fib");
234 commandName.append("add-nexthop");
235 commandName.append(encodedOptions);
236
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700237 face->onReceiveData +=
238 bind(&FibManagerFixture::validateControlResponse, this, _1,
239 commandName, 404, "Prefix not found");
240 /// \todo enable once sig checking implemented
241 // bind(&FibManagerFixture::validateControlResponse, this, _1, 403, "Unauthorized command");
242
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700243 Interest command(commandName);
244 manager.onFibRequest(command);
245
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700246 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700247 BOOST_REQUIRE(!addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700248}
249
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700250BOOST_FIXTURE_TEST_CASE(BadOptionParse, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700251{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700252 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700253
254 shared_ptr<InternalFace> face(make_shared<InternalFace>());
255 Fib fib;
256 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700257 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700258 face);
259
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700260 Name commandName("/localhost/nfd/fib");
261 commandName.append("add-nexthop");
262 commandName.append("NotReallyOptions");
263
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700264 face->onReceiveData +=
265 bind(&FibManagerFixture::validateControlResponse, this, _1,
266 commandName, 400, "Malformed command");
267
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700268 Interest command(commandName);
269 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700270
271 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700272}
273
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700274BOOST_FIXTURE_TEST_CASE(UnknownFaceId, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700275{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700276 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700277
278 shared_ptr<InternalFace> face(make_shared<InternalFace>());
279 Fib fib;
280 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);
283
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800284 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700285 options.setName("/hello");
286 options.setFaceId(1000);
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, "Face not found");
298
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700299 Interest command(commandName);
300 manager.onFibRequest(command);
301
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700302 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700303 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
304}
305
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700306BOOST_FIXTURE_TEST_CASE(AddNextHopVerbInitialAdd, FibManagerFixture)
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700307{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700308 addFace(make_shared<DummyFace>());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700309
310 shared_ptr<InternalFace> face(make_shared<InternalFace>());
311 Fib fib;
312 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700313 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700314 face);
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700315
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800316 FibManagementOptions options;
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700317 options.setName("/hello");
318 options.setFaceId(1);
319 options.setCost(101);
320
321 Block encodedOptions(options.wireEncode());
322
323 Name commandName("/localhost/nfd/fib");
324 commandName.append("add-nexthop");
325 commandName.append(encodedOptions);
326
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700327 face->onReceiveData +=
328 bind(&FibManagerFixture::validateControlResponse, this, _1,
329 commandName, 200, "OK");
330
331 fib.insert("/hello");
332
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700333 Interest command(commandName);
334 manager.onFibRequest(command);
335
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700336 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700337 BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700338}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700339
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700340BOOST_FIXTURE_TEST_CASE(AddNextHopVerbAddToExisting, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700341{
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700342 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700343
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700344 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700345 Fib fib;
346 FibManager manager(fib,
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700347 bind(&FibManagerFixture::getFace, this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700348 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700349
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700350 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700351
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700352 for (int i = 1; i <= 2; i++)
353 {
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700354
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800355 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700356 options.setName("/hello");
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700357 options.setFaceId(1);
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700358 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700359
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700360 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700361
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700362 Name commandName("/localhost/nfd/fib");
363 commandName.append("add-nexthop");
364 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700365
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700366 face->onReceiveData +=
367 bind(&FibManagerFixture::validateControlResponse, this, _1,
368 commandName, 200, "OK");
369
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700370 Interest command(commandName);
371 manager.onFibRequest(command);
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700372 BOOST_REQUIRE(didCallbackFire());
373 resetCallbackFired();
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700374
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700375 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700376
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700377 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700378 {
379 const fib::NextHopList& hops = entry->getNextHops();
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700380 BOOST_REQUIRE(hops.size() == 1);
381 BOOST_REQUIRE(std::find_if(hops.begin(), hops.end(),
382 bind(&foundNextHop, -1, 100 + i, _1)) != hops.end());
383
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700384 }
385 else
386 {
387 BOOST_FAIL("Failed to find expected fib entry");
388 }
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700389
390 face->onReceiveData.clear();
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700391 }
392}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700393
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700394BOOST_FIXTURE_TEST_CASE(AddNextHopVerbUpdateFaceCost, FibManagerFixture)
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700395{
396 FibManagerFixture fixture;
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700397 addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700398
Steve DiBenedetto80ddc212014-02-01 22:23:56 -0700399 shared_ptr<InternalFace> face(make_shared<InternalFace>());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700400 Fib fib;
401 FibManager manager(fib,
402 bind(&FibManagerFixture::getFace,
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700403 this, _1),
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700404 face);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700405
406 fib.insert("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700407
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800408 FibManagementOptions options;
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700409 options.setName("/hello");
410 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700411
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700412 {
413 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700414
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700415 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700416
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700417 Name commandName("/localhost/nfd/fib");
418 commandName.append("add-nexthop");
419 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700420
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700421 face->onReceiveData +=
422 bind(&FibManagerFixture::validateControlResponse, this, _1,
423 commandName, 200, "OK");
424
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700425 Interest command(commandName);
426 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700427
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700428 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700429 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700430
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700431 resetCallbackFired();
432 face->onReceiveData.clear();
433
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700434 {
435 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700436
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700437 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700438
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700439 Name commandName("/localhost/nfd/fib");
440 commandName.append("add-nexthop");
441 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700442
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700443 face->onReceiveData +=
444 bind(&FibManagerFixture::validateControlResponse, this, _1,
445 commandName, 200, "OK");
446
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700447 Interest command(commandName);
448 manager.onFibRequest(command);
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700449
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700450 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700451 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700452
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700453 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700454
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700455 // Add faces with cost == FaceID for the name /hello
456 // This test assumes:
457 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedettobdedce92014-02-02 22:49:39 -0700458 if (static_cast<bool>(entry))
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700459 {
460 const fib::NextHopList& hops = entry->getNextHops();
461 BOOST_REQUIRE(hops.size() == 1);
462 BOOST_REQUIRE(std::find_if(hops.begin(),
463 hops.end(),
464 bind(&foundNextHop, -1, 102, _1)) != hops.end());
465 }
466 else
467 {
468 BOOST_FAIL("Failed to find expected fib entry");
469 }
470}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700471
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700472BOOST_FIXTURE_TEST_CASE(Insert, FibManagerFixture)
473{
474 shared_ptr<InternalFace> face(make_shared<InternalFace>());
475 Fib fib;
476 FibManager manager(fib,
477 bind(&FibManagerFixture::getFace, this, _1),
478 face);
479
480 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800481 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700482 options.setName("/hello");
483
484 Block encodedOptions(options.wireEncode());
485
486 Name commandName("/localhost/nfd/fib");
487 commandName.append("insert");
488 commandName.append(encodedOptions);
489
490 face->onReceiveData +=
491 bind(&FibManagerFixture::validateControlResponse, this, _1,
492 commandName, 200, "OK");
493
494 Interest command(commandName);
495 manager.onFibRequest(command);
496 }
497
498 BOOST_REQUIRE(didCallbackFire());
499
500 shared_ptr<fib::Entry> entry = fib.findExactMatch("/hello");
501 if (static_cast<bool>(entry))
502 {
503 const fib::NextHopList& hops = entry->getNextHops();
504 BOOST_CHECK_EQUAL(hops.size(), 0);
505 }
506
507 resetCallbackFired();
508
509 {
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800510 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700511 options.setName("/hello");
512
513 Block encodedOptions(options.wireEncode());
514
515 Name commandName("/localhost/nfd/fib");
516 commandName.append("insert");
517 commandName.append(encodedOptions);
518
519 face->onReceiveData +=
520 bind(&FibManagerFixture::validateControlResponse, this, _1,
521 commandName, 200, "OK");
522
523 Interest command(commandName);
524 manager.onFibRequest(command);
525 }
526
527 BOOST_REQUIRE(didCallbackFire());
528
529 entry = fib.findExactMatch("/hello");
530 if (static_cast<bool>(entry))
531 {
532 const fib::NextHopList& hops = entry->getNextHops();
533 BOOST_CHECK_EQUAL(hops.size(), 0);
534 }
535
536}
537
538void
539testRemove(FibManagerFixture* fixture,
540 FibManager& manager,
541 Fib& fib,
542 shared_ptr<Face> face,
543 const Name& target)
544{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800545 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700546 options.setName(target);
547
548 Block encodedOptions(options.wireEncode());
549
550 Name commandName("/localhost/nfd/fib");
551 commandName.append("delete");
552 commandName.append(encodedOptions);
553
554 face->onReceiveData +=
555 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
556 commandName, 200, "OK");
557
558 Interest command(commandName);
559 manager.onFibRequest(command);
560
561 BOOST_REQUIRE(fixture->didCallbackFire());
562
563 if (static_cast<bool>(fib.findExactMatch(target)))
564 {
565 BOOST_FAIL("Found \"removed\" prefix");
566 }
567 face->onReceiveData.clear();
568}
569
570BOOST_FIXTURE_TEST_CASE(Delete, FibManagerFixture)
571{
572 shared_ptr<InternalFace> face(make_shared<InternalFace>());
573 Fib fib;
574 FibManager manager(fib,
575 bind(&FibManagerFixture::getFace, this, _1),
576 face);
577
578 fib.insert("/a");
579 fib.insert("/a/b");
580 fib.insert("/a/b/c");
581
582 testRemove(this, manager, fib, face, "/");
583
584 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
585 !static_cast<bool>(fib.findExactMatch("/a/b")) ||
586 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
587 {
588 BOOST_FAIL("Removed incorrect entry");
589 }
590
591 testRemove(this, manager, fib, face, "/a/b");
592
593 if (!static_cast<bool>(fib.findExactMatch("/a")) ||
594 !static_cast<bool>(fib.findExactMatch("/a/b/c")))
595 {
596 BOOST_FAIL("Removed incorrect entry");
597 }
598
599 testRemove(this, manager, fib, face, "/a/b/c");
600
601 if (!static_cast<bool>(fib.findExactMatch("/a")))
602 {
603 BOOST_FAIL("Removed incorrect entry");
604 }
605
606 testRemove(this, manager, fib, face, "/a");
607
608 testRemove(this, manager, fib, face, "/does/not/exist");
609}
610
611bool
612removedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
613{
614 shared_ptr<fib::Entry> entry = fib.findExactMatch(prefix);
615
616 if (static_cast<bool>(entry))
617 {
618 const fib::NextHopList& hops = entry->getNextHops();
619 return hops.size() == oldSize - 1 &&
620 std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) == hops.end();
621 }
622 return false;
623}
624
625void
626testRemoveNextHop(FibManagerFixture* fixture,
627 FibManager& manager,
628 Fib& fib,
629 shared_ptr<Face> face,
630 const Name& targetName,
631 FaceId targetFace)
632{
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800633 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700634 options.setName(targetName);
635 options.setFaceId(targetFace);
636
637 Block encodedOptions(options.wireEncode());
638
639 Name commandName("/localhost/nfd/fib");
640 commandName.append("remove-nexthop");
641 commandName.append(encodedOptions);
642
643 face->onReceiveData +=
644 bind(&FibManagerFixture::validateControlResponse, fixture, _1,
645 commandName, 200, "OK");
646
647 Interest command(commandName);
648 manager.onFibRequest(command);
649
650 BOOST_REQUIRE(fixture->didCallbackFire());
651
652 fixture->resetCallbackFired();
653 face->onReceiveData.clear();
654}
655
656BOOST_FIXTURE_TEST_CASE(RemoveNextHop, FibManagerFixture)
657{
658 shared_ptr<Face> face1 = make_shared<DummyFace>();
659 shared_ptr<Face> face2 = make_shared<DummyFace>();
660 shared_ptr<Face> face3 = make_shared<DummyFace>();
661
662 addFace(face1);
663 addFace(face2);
664 addFace(face3);
665
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 shared_ptr<fib::Entry> entry = fib.insert("/hello").first;
673
674 entry->addNextHop(face1, 101);
675 entry->addNextHop(face2, 202);
676 entry->addNextHop(face3, 303);
677
678 testRemoveNextHop(this, manager, fib, face, "/hello", 2);
679 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 3, 202));
680
681 testRemoveNextHop(this, manager, fib, face, "/hello", 3);
682 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 2, 303));
683
684 testRemoveNextHop(this, manager, fib, face, "/hello", 1);
685 BOOST_REQUIRE(removedNextHopWithCost(fib, "/hello", 1, 101));
686
687 if (!static_cast<bool>(fib.findExactMatch("/hello")))
688 {
689 BOOST_FAIL("removed entry after removing all next hops");
690 }
691
692}
693
694BOOST_FIXTURE_TEST_CASE(RemoveNoFace, FibManagerFixture)
695{
696 shared_ptr<InternalFace> face(make_shared<InternalFace>());
697 Fib fib;
698 FibManager manager(fib,
699 bind(&FibManagerFixture::getFace, this, _1),
700 face);
701
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800702 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700703 options.setName("/hello");
704 options.setFaceId(1);
705
706 Block encodedOptions(options.wireEncode());
707
708 Name commandName("/localhost/nfd/fib");
709 commandName.append("remove-nexthop");
710 commandName.append(encodedOptions);
711
712 face->onReceiveData +=
713 bind(&FibManagerFixture::validateControlResponse, this, _1,
714 commandName, 404, "Face not found");
715
716 Interest command(commandName);
717 manager.onFibRequest(command);
718
719 BOOST_REQUIRE(didCallbackFire());
720}
721
722BOOST_FIXTURE_TEST_CASE(RemoveNoPrefix, FibManagerFixture)
723{
724 addFace(make_shared<DummyFace>());
725
726 shared_ptr<InternalFace> face(make_shared<InternalFace>());
727 Fib fib;
728 FibManager manager(fib,
729 bind(&FibManagerFixture::getFace, this, _1),
730 face);
731
Alexander Afanasyevd482fd32014-02-09 23:40:20 -0800732 FibManagementOptions options;
Steve DiBenedetto0b73f442014-02-05 22:02:03 -0700733 options.setName("/hello");
734 options.setFaceId(1);
735
736 Block encodedOptions(options.wireEncode());
737
738 Name commandName("/localhost/nfd/fib");
739 commandName.append("remove-nexthop");
740 commandName.append(encodedOptions);
741
742 face->onReceiveData +=
743 bind(&FibManagerFixture::validateControlResponse, this, _1,
744 commandName, 404, "Prefix not found");
745
746 Interest command(commandName);
747 manager.onFibRequest(command);
748
749 BOOST_REQUIRE(didCallbackFire());
750}
751
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700752BOOST_AUTO_TEST_SUITE_END()
753
754} // namespace nfd