blob: 161e2f797eb68a01297f503dd090110c45cef625 [file] [log] [blame]
Yanbiao Li711c7932015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yanbiao Lidf846e52016-01-30 21:53:47 -08003 * Copyright (c) 2014-2016, Regents of the University of California,
Yanbiao Li711c7932015-08-19 16:30:16 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
Davide Pesavento97210d52016-10-14 15:45:48 +020025
Yanbiao Li711c7932015-08-19 16:30:16 -070026#include "mgmt/fib-manager.hpp"
Davide Pesavento97210d52016-10-14 15:45:48 +020027#include "table/fib-nexthop.hpp"
Yanbiao Li711c7932015-08-19 16:30:16 -070028
Yanbiao Lidf846e52016-01-30 21:53:47 -080029#include "nfd-manager-common-fixture.hpp"
Yanbiao Li711c7932015-08-19 16:30:16 -070030#include "../face/dummy-face.hpp"
Davide Pesavento97210d52016-10-14 15:45:48 +020031
Junxiao Shicbc8e942016-09-06 03:17:45 +000032#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000033#include <ndn-cxx/mgmt/nfd/fib-entry.hpp>
Yanbiao Li711c7932015-08-19 16:30:16 -070034
35namespace nfd {
36namespace tests {
37
Yanbiao Lidf846e52016-01-30 21:53:47 -080038class FibManagerFixture : public NfdManagerCommonFixture
Yanbiao Li711c7932015-08-19 16:30:16 -070039{
40public:
41 FibManagerFixture()
42 : m_fib(m_forwarder.getFib())
43 , m_faceTable(m_forwarder.getFaceTable())
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000044 , m_manager(m_fib, m_faceTable, m_dispatcher, *m_authenticator)
Yanbiao Li711c7932015-08-19 16:30:16 -070045 {
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000046 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080047 setPrivilege("fib");
Yanbiao Li711c7932015-08-19 16:30:16 -070048 }
49
50public: // for test
51 ControlParameters
52 makeParameters(const Name& name, const FaceId& id)
53 {
54 return ControlParameters().setName(name).setFaceId(id);
55 }
56
57 ControlParameters
58 makeParameters(const Name& name, const FaceId& id, const uint32_t& cost)
59 {
60 return ControlParameters().setName(name).setFaceId(id).setCost(cost);
61 }
62
63 FaceId
64 addFace()
65 {
66 auto face = make_shared<DummyFace>();
67 m_faceTable.add(face);
68 advanceClocks(time::milliseconds(1), 10);
69 m_responses.clear(); // clear all event notifications, if any
70 return face->getId();
71 }
72
73public: // for check
74 enum class CheckNextHopResult
75 {
76 OK,
77 NO_FIB_ENTRY,
78 WRONG_N_NEXTHOPS,
79 NO_NEXTHOP,
80 WRONG_COST
81 };
82
83 /**
84 * @brief check whether the nexthop record is added / removed properly
85 *
86 * @param expectedNNextHops use -1 to skip this check
Junxiao Shicde37ad2015-12-24 01:02:05 -070087 * @param faceId use face::FACEID_NULL to skip NextHopRecord checks
Yanbiao Li711c7932015-08-19 16:30:16 -070088 * @param expectedCost use -1 to skip this check
89 *
90 * @retval OK FIB entry is found by exact match and has the expected number of nexthops;
91 * NextHopRe record for faceId is found and has the expected cost
92 * @retval NO_FIB_ENTRY FIB entry is not found
93 * @retval WRONG_N_NEXTHOPS FIB entry is found but has wrong number of nexthops
94 * @retval NO_NEXTHOP NextHopRecord for faceId is not found
95 * @retval WRONG_COST NextHopRecord for faceId has wrong cost
96 */
97 CheckNextHopResult
98 checkNextHop(const Name& prefix, ssize_t expectedNNextHops = -1,
Junxiao Shicde37ad2015-12-24 01:02:05 -070099 FaceId faceId = face::FACEID_NULL, int32_t expectedCost = -1)
Yanbiao Li711c7932015-08-19 16:30:16 -0700100 {
Junxiao Shia6de4292016-07-12 02:08:10 +0000101 const fib::Entry* entry = m_fib.findExactMatch(prefix);
102 if (entry == nullptr) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700103 return CheckNextHopResult::NO_FIB_ENTRY;
104 }
105
Junxiao Shia6de4292016-07-12 02:08:10 +0000106 const fib::NextHopList& nextHops = entry->getNextHops();
Yanbiao Li711c7932015-08-19 16:30:16 -0700107 if (expectedNNextHops != -1 && nextHops.size() != static_cast<size_t>(expectedNNextHops)) {
108 return CheckNextHopResult::WRONG_N_NEXTHOPS;
109 }
110
Junxiao Shicde37ad2015-12-24 01:02:05 -0700111 if (faceId != face::FACEID_NULL) {
Davide Pesavento97210d52016-10-14 15:45:48 +0200112 for (const auto& record : nextHops) {
Junxiao Shia6de4292016-07-12 02:08:10 +0000113 if (record.getFace().getId() == faceId) {
Davide Pesavento97210d52016-10-14 15:45:48 +0200114 if (expectedCost != -1 && record.getCost() != static_cast<uint32_t>(expectedCost))
115 return CheckNextHopResult::WRONG_COST;
116 else
117 return CheckNextHopResult::OK;
Yanbiao Li711c7932015-08-19 16:30:16 -0700118 }
119 }
Yanbiao Li711c7932015-08-19 16:30:16 -0700120 return CheckNextHopResult::NO_NEXTHOP;
121 }
Yanbiao Li711c7932015-08-19 16:30:16 -0700122 return CheckNextHopResult::OK;
123 }
124
125protected:
126 Fib& m_fib;
127 FaceTable& m_faceTable;
128 FibManager m_manager;
129};
130
131std::ostream&
132operator<<(std::ostream &os, const FibManagerFixture::CheckNextHopResult& result)
133{
134 switch (result) {
135 case FibManagerFixture::CheckNextHopResult::OK:
136 os << "OK";
137 break;
138 case FibManagerFixture::CheckNextHopResult::NO_FIB_ENTRY:
139 os << "NO_FIB_ENTRY";
140 break;
141 case FibManagerFixture::CheckNextHopResult::WRONG_N_NEXTHOPS:
142 os << "WRONG_N_NEXTHOPS";
143 break;
144 case FibManagerFixture::CheckNextHopResult::NO_NEXTHOP:
145 os << "NO_NEXTHOP";
146 break;
147 case FibManagerFixture::CheckNextHopResult::WRONG_COST:
148 os << "WRONG_COST";
149 break;
150 default:
151 break;
152 };
153
154 return os;
155}
156
Davide Pesavento97210d52016-10-14 15:45:48 +0200157BOOST_AUTO_TEST_SUITE(Mgmt)
158BOOST_FIXTURE_TEST_SUITE(TestFibManager, FibManagerFixture)
Yanbiao Li711c7932015-08-19 16:30:16 -0700159
160BOOST_AUTO_TEST_SUITE(AddNextHop)
161
162BOOST_AUTO_TEST_CASE(UnknownFaceId)
163{
164 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop",
Junxiao Shicde37ad2015-12-24 01:02:05 -0700165 makeParameters("hello", face::FACEID_NULL, 101));
Yanbiao Li711c7932015-08-19 16:30:16 -0700166 receiveInterest(command);
167 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
168
169 // check response
170 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), ControlResponse(410, "Face not found")),
171 CheckResponseResult::OK);
172
173 // double check that the next hop was not added
Junxiao Shicde37ad2015-12-24 01:02:05 -0700174 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face::FACEID_NULL, 101), CheckNextHopResult::NO_FIB_ENTRY);
Yanbiao Li711c7932015-08-19 16:30:16 -0700175}
176
177BOOST_AUTO_TEST_CASE(ImplicitFaceId)
178{
179 auto face1 = addFace();
180 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700181 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
182 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700183
184 Name expectedName;
185 ControlResponse expectedResponse;
186 auto testAddNextHop = [&] (ControlParameters parameters, const FaceId& faceId) {
187 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000188 [&faceId] (shared_ptr<Interest> interest) {
189 interest->setTag(make_shared<lp::IncomingFaceIdTag>(faceId));
190 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700191 m_responses.clear();
192 expectedName = command->getName();
193 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
194 receiveInterest(command);
195 };
196
197 testAddNextHop(ControlParameters().setName("/hello").setCost(100).setFaceId(0), face1);
198 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
199 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
200 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 100), CheckNextHopResult::OK);
201
202 testAddNextHop(ControlParameters().setName("/hello").setCost(100), face2);
203 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
204 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
205 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face2, 100), CheckNextHopResult::OK);
206}
207
208BOOST_AUTO_TEST_CASE(InitialAdd)
209{
210 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700211 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700212
213 auto parameters = makeParameters("hello", addedFaceId, 101);
214 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
215
216 receiveInterest(command);
217 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
218 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
219 CheckResponseResult::OK);
220 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 101), CheckNextHopResult::OK);
221}
222
223BOOST_AUTO_TEST_CASE(ImplicitCost)
224{
225 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700226 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700227
228 auto originalParameters = ControlParameters().setName("/hello").setFaceId(addedFaceId);
229 auto parameters = makeParameters("/hello", addedFaceId, 0);
230 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", originalParameters);
231
232 receiveInterest(command);
233 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
234 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
235 CheckResponseResult::OK);
236 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 0), CheckNextHopResult::OK);
237}
238
239BOOST_AUTO_TEST_CASE(AddToExisting)
240{
241 FaceId face = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700242 BOOST_REQUIRE_NE(face, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700243
244 Name expectedName;
245 ControlResponse expectedResponse;
246 auto testAddNextHop = [&] (const ControlParameters& parameters) {
247 m_responses.clear();
248 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
249 expectedName = command->getName();
250 expectedResponse = makeResponse(200, "Success", parameters);
251 receiveInterest(command);
252 };
253
254 // add initial, succeeds
255 testAddNextHop(makeParameters("/hello", face, 101));
256 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
257 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
258
259 // add to existing --> update cost, succeeds
260 testAddNextHop(makeParameters("/hello", face, 102));
261 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
262 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
263
264 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face, 102), CheckNextHopResult::WRONG_N_NEXTHOPS);
265 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 101), CheckNextHopResult::WRONG_COST);
266 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 102), CheckNextHopResult::OK);
267}
268
269BOOST_AUTO_TEST_SUITE_END() // AddNextHop
270
271BOOST_AUTO_TEST_SUITE(RemoveNextHop)
272
273BOOST_AUTO_TEST_CASE(Basic)
274{
275 Name expectedName;
276 ControlResponse expectedResponse;
277 auto testRemoveNextHop = [&] (const ControlParameters& parameters) {
278 m_responses.clear();
279 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
280 expectedName = command->getName();
281 expectedResponse = makeResponse(200, "Success", parameters);
282 receiveInterest(command);
283 };
284
285 FaceId face1 = addFace();
286 FaceId face2 = addFace();
287 FaceId face3 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700288 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
289 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
290 BOOST_REQUIRE_NE(face3, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700291
Junxiao Shia6de4292016-07-12 02:08:10 +0000292 fib::Entry* entry = m_fib.insert("/hello").first;
293 entry->addNextHop(*m_faceTable.get(face1), 101);
294 entry->addNextHop(*m_faceTable.get(face2), 202);
295 entry->addNextHop(*m_faceTable.get(face3), 303);
Yanbiao Li711c7932015-08-19 16:30:16 -0700296
297 testRemoveNextHop(makeParameters("/hello", face1));
298 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
299 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
300 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face1, 101), CheckNextHopResult::NO_NEXTHOP);
301
302 testRemoveNextHop(makeParameters("/hello", face2));
303 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
304 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
305 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face2, 202), CheckNextHopResult::NO_NEXTHOP);
306
307 testRemoveNextHop(makeParameters("/hello", face3));
308 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
309 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
310 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face3, 303), CheckNextHopResult::NO_FIB_ENTRY);
311}
312
313BOOST_AUTO_TEST_CASE(PrefixNotFound)
314{
315 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700316 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700317
318 auto parameters = makeParameters("hello", addedFaceId);
319 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
320 auto response = makeResponse(200, "Success", parameters);
321
322 receiveInterest(command);
323 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
324 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), response), CheckResponseResult::OK);
325}
326
327BOOST_AUTO_TEST_CASE(ImplicitFaceId)
328{
329 auto face1 = addFace();
330 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700331 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
332 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700333
334 Name expectedName;
335 ControlResponse expectedResponse;
336 auto testWithImplicitFaceId = [&] (ControlParameters parameters, FaceId face) {
337 m_responses.clear();
338 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000339 [face] (shared_ptr<Interest> interest) {
340 interest->setTag(make_shared<lp::IncomingFaceIdTag>(face));
341 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700342 expectedName = command->getName();
343 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
344 receiveInterest(command);
345 };
346
Junxiao Shia6de4292016-07-12 02:08:10 +0000347 fib::Entry* entry = m_fib.insert("/hello").first;
348 entry->addNextHop(*m_faceTable.get(face1), 101);
349 entry->addNextHop(*m_faceTable.get(face2), 202);
Yanbiao Li711c7932015-08-19 16:30:16 -0700350
351 testWithImplicitFaceId(ControlParameters().setName("/hello").setFaceId(0), face1);
352 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
353 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
354 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 101), CheckNextHopResult::NO_NEXTHOP);
355
356 testWithImplicitFaceId(ControlParameters().setName("/hello"), face2);
357 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
358 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
359 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face2, 202), CheckNextHopResult::NO_FIB_ENTRY);
360}
361
362BOOST_AUTO_TEST_CASE(RecordNotExist)
363{
364 auto face1 = addFace();
365 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700366 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
367 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700368
369 Name expectedName;
370 ControlResponse expectedResponse;
371 auto testRemoveNextHop = [&] (ControlParameters parameters) {
372 m_responses.clear();
373 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
374 expectedName = command->getName();
375 expectedResponse = makeResponse(200, "Success", parameters);
376 receiveInterest(command);
377 };
378
Junxiao Shia6de4292016-07-12 02:08:10 +0000379 m_fib.insert("/hello").first->addNextHop(*m_faceTable.get(face1), 101);
Yanbiao Li711c7932015-08-19 16:30:16 -0700380
381 testRemoveNextHop(makeParameters("/hello", face2 + 100));
382 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // face does not exist
383 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
384 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2 + 100), CheckNextHopResult::NO_NEXTHOP);
385
386 testRemoveNextHop(makeParameters("/hello", face2));
387 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // record does not exist
388 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
389 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2), CheckNextHopResult::NO_NEXTHOP);
390}
391
392BOOST_AUTO_TEST_SUITE_END() // RemoveNextHop
393
Davide Pesavento97210d52016-10-14 15:45:48 +0200394BOOST_AUTO_TEST_SUITE(List)
395
Yanbiao Li711c7932015-08-19 16:30:16 -0700396// @todo Remove when ndn::nfd::FibEntry implements operator!= and operator<<
397class FibEntry : public ndn::nfd::FibEntry
398{
399public:
400 FibEntry() = default;
401
402 FibEntry(const ndn::nfd::FibEntry& entry)
403 : ndn::nfd::FibEntry(entry)
404 {
405 }
406};
407
408bool
409operator!=(const FibEntry& left, const FibEntry& right)
410{
411 if (left.getPrefix() != right.getPrefix()) {
412 return true;
413 }
414
Davide Pesavento97210d52016-10-14 15:45:48 +0200415 const auto& leftNextHops = left.getNextHopRecords();
416 const auto& rightNextHops = right.getNextHopRecords();
Yanbiao Li711c7932015-08-19 16:30:16 -0700417 if (leftNextHops.size() != rightNextHops.size()) {
418 return true;
419 }
420
Davide Pesavento97210d52016-10-14 15:45:48 +0200421 for (const auto& nexthop : leftNextHops) {
422 auto hitEntry = std::find_if(rightNextHops.begin(), rightNextHops.end(),
423 [&] (const ndn::nfd::NextHopRecord& record) {
424 return nexthop.getCost() == record.getCost() && nexthop.getFaceId() == record.getFaceId();
425 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700426
427 if (hitEntry == rightNextHops.end()) {
428 return true;
429 }
430 }
431
432 return false;
433}
434
435std::ostream&
436operator<<(std::ostream &os, const FibEntry& entry)
437{
438 const auto& nexthops = entry.getNextHopRecords();
439 os << "[" << entry.getPrefix() << ", " << nexthops.size() << ": ";
440 for (auto record : nexthops) {
441 os << "{" << record.getFaceId() << ", " << record.getCost() << "} ";
442 }
443 os << "]";
444
445 return os;
446}
447
448BOOST_AUTO_TEST_CASE(FibDataset)
449{
450 const size_t nEntries = 108;
451 std::set<Name> actualPrefixes;
452 for (size_t i = 0 ; i < nEntries ; i ++) {
453 Name prefix = Name("test").appendSegment(i);
454 actualPrefixes.insert(prefix);
Junxiao Shia6de4292016-07-12 02:08:10 +0000455 fib::Entry* fibEntry = m_fib.insert(prefix).first;
456 fibEntry->addNextHop(*m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 1);
457 fibEntry->addNextHop(*m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 2);
Yanbiao Li711c7932015-08-19 16:30:16 -0700458 }
459
460 receiveInterest(makeInterest("/localhost/nfd/fib/list"));
461
462 Block content;
463 BOOST_CHECK_NO_THROW(content = concatenateResponses());
464 BOOST_CHECK_NO_THROW(content.parse());
465 BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
466
467 std::vector<FibEntry> receivedRecords, expectedRecords;
468 for (size_t idx = 0; idx < nEntries; ++idx) {
469 BOOST_TEST_MESSAGE("processing element: " << idx);
470
471 FibEntry decodedEntry;
472 BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
473 receivedRecords.push_back(decodedEntry);
474
475 actualPrefixes.erase(decodedEntry.getPrefix());
476
477 auto matchedEntry = m_fib.findExactMatch(decodedEntry.getPrefix());
478 BOOST_REQUIRE(matchedEntry != nullptr);
479
480 FibEntry record;
481 record.setPrefix(matchedEntry->getPrefix());
482 const auto& nextHops = matchedEntry->getNextHops();
Davide Pesavento97210d52016-10-14 15:45:48 +0200483 for (const auto& next : nextHops) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700484 ndn::nfd::NextHopRecord nextHopRecord;
Junxiao Shia6de4292016-07-12 02:08:10 +0000485 nextHopRecord.setFaceId(next.getFace().getId());
Yanbiao Li711c7932015-08-19 16:30:16 -0700486 nextHopRecord.setCost(next.getCost());
487 record.addNextHopRecord(nextHopRecord);
488 }
489 expectedRecords.push_back(record);
490 }
491
492 BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
Yanbiao Li711c7932015-08-19 16:30:16 -0700493 BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
494 expectedRecords.begin(), expectedRecords.end());
495}
496
Davide Pesavento97210d52016-10-14 15:45:48 +0200497BOOST_AUTO_TEST_SUITE_END() // List
498
Yanbiao Li711c7932015-08-19 16:30:16 -0700499BOOST_AUTO_TEST_SUITE_END() // TestFibManager
500BOOST_AUTO_TEST_SUITE_END() // Mgmt
501
502} // namespace tests
503} // namespace nfd