blob: 4bc642e082acfbfbb6902c5e4f75f1f4ea86f866 [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 */
25#include "mgmt/fib-manager.hpp"
26
Yanbiao Lidf846e52016-01-30 21:53:47 -080027#include "nfd-manager-common-fixture.hpp"
Yanbiao Li711c7932015-08-19 16:30:16 -070028#include "table/fib-nexthop.hpp"
29#include "../face/dummy-face.hpp"
Junxiao Shicbc8e942016-09-06 03:17:45 +000030#include <ndn-cxx/lp/tags.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000031#include <ndn-cxx/mgmt/nfd/fib-entry.hpp>
Yanbiao Li711c7932015-08-19 16:30:16 -070032
33namespace nfd {
34namespace tests {
35
Yanbiao Lidf846e52016-01-30 21:53:47 -080036class FibManagerFixture : public NfdManagerCommonFixture
Yanbiao Li711c7932015-08-19 16:30:16 -070037{
38public:
39 FibManagerFixture()
40 : m_fib(m_forwarder.getFib())
41 , m_faceTable(m_forwarder.getFaceTable())
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000042 , m_manager(m_fib, m_faceTable, m_dispatcher, *m_authenticator)
Yanbiao Li711c7932015-08-19 16:30:16 -070043 {
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000044 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080045 setPrivilege("fib");
Yanbiao Li711c7932015-08-19 16:30:16 -070046 }
47
48public: // for test
49 ControlParameters
50 makeParameters(const Name& name, const FaceId& id)
51 {
52 return ControlParameters().setName(name).setFaceId(id);
53 }
54
55 ControlParameters
56 makeParameters(const Name& name, const FaceId& id, const uint32_t& cost)
57 {
58 return ControlParameters().setName(name).setFaceId(id).setCost(cost);
59 }
60
61 FaceId
62 addFace()
63 {
64 auto face = make_shared<DummyFace>();
65 m_faceTable.add(face);
66 advanceClocks(time::milliseconds(1), 10);
67 m_responses.clear(); // clear all event notifications, if any
68 return face->getId();
69 }
70
71public: // for check
72 enum class CheckNextHopResult
73 {
74 OK,
75 NO_FIB_ENTRY,
76 WRONG_N_NEXTHOPS,
77 NO_NEXTHOP,
78 WRONG_COST
79 };
80
81 /**
82 * @brief check whether the nexthop record is added / removed properly
83 *
84 * @param expectedNNextHops use -1 to skip this check
Junxiao Shicde37ad2015-12-24 01:02:05 -070085 * @param faceId use face::FACEID_NULL to skip NextHopRecord checks
Yanbiao Li711c7932015-08-19 16:30:16 -070086 * @param expectedCost use -1 to skip this check
87 *
88 * @retval OK FIB entry is found by exact match and has the expected number of nexthops;
89 * NextHopRe record for faceId is found and has the expected cost
90 * @retval NO_FIB_ENTRY FIB entry is not found
91 * @retval WRONG_N_NEXTHOPS FIB entry is found but has wrong number of nexthops
92 * @retval NO_NEXTHOP NextHopRecord for faceId is not found
93 * @retval WRONG_COST NextHopRecord for faceId has wrong cost
94 */
95 CheckNextHopResult
96 checkNextHop(const Name& prefix, ssize_t expectedNNextHops = -1,
Junxiao Shicde37ad2015-12-24 01:02:05 -070097 FaceId faceId = face::FACEID_NULL, int32_t expectedCost = -1)
Yanbiao Li711c7932015-08-19 16:30:16 -070098 {
Junxiao Shia6de4292016-07-12 02:08:10 +000099 const fib::Entry* entry = m_fib.findExactMatch(prefix);
100 if (entry == nullptr) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700101 return CheckNextHopResult::NO_FIB_ENTRY;
102 }
103
Junxiao Shia6de4292016-07-12 02:08:10 +0000104 const fib::NextHopList& nextHops = entry->getNextHops();
Yanbiao Li711c7932015-08-19 16:30:16 -0700105 if (expectedNNextHops != -1 && nextHops.size() != static_cast<size_t>(expectedNNextHops)) {
106 return CheckNextHopResult::WRONG_N_NEXTHOPS;
107 }
108
Junxiao Shicde37ad2015-12-24 01:02:05 -0700109 if (faceId != face::FACEID_NULL) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700110 for (auto&& record : nextHops) {
Junxiao Shia6de4292016-07-12 02:08:10 +0000111 if (record.getFace().getId() == faceId) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700112 return expectedCost != -1 && record.getCost() != static_cast<uint32_t>(expectedCost) ?
113 CheckNextHopResult::WRONG_COST : CheckNextHopResult::OK;
114 }
115 }
116
117 return CheckNextHopResult::NO_NEXTHOP;
118 }
119
120 return CheckNextHopResult::OK;
121 }
122
123protected:
124 Fib& m_fib;
125 FaceTable& m_faceTable;
126 FibManager m_manager;
127};
128
129std::ostream&
130operator<<(std::ostream &os, const FibManagerFixture::CheckNextHopResult& result)
131{
132 switch (result) {
133 case FibManagerFixture::CheckNextHopResult::OK:
134 os << "OK";
135 break;
136 case FibManagerFixture::CheckNextHopResult::NO_FIB_ENTRY:
137 os << "NO_FIB_ENTRY";
138 break;
139 case FibManagerFixture::CheckNextHopResult::WRONG_N_NEXTHOPS:
140 os << "WRONG_N_NEXTHOPS";
141 break;
142 case FibManagerFixture::CheckNextHopResult::NO_NEXTHOP:
143 os << "NO_NEXTHOP";
144 break;
145 case FibManagerFixture::CheckNextHopResult::WRONG_COST:
146 os << "WRONG_COST";
147 break;
148 default:
149 break;
150 };
151
152 return os;
153}
154
155BOOST_FIXTURE_TEST_SUITE(Mgmt, FibManagerFixture)
156BOOST_AUTO_TEST_SUITE(TestFibManager)
157
158BOOST_AUTO_TEST_SUITE(AddNextHop)
159
160BOOST_AUTO_TEST_CASE(UnknownFaceId)
161{
162 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop",
Junxiao Shicde37ad2015-12-24 01:02:05 -0700163 makeParameters("hello", face::FACEID_NULL, 101));
Yanbiao Li711c7932015-08-19 16:30:16 -0700164 receiveInterest(command);
165 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
166
167 // check response
168 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), ControlResponse(410, "Face not found")),
169 CheckResponseResult::OK);
170
171 // double check that the next hop was not added
Junxiao Shicde37ad2015-12-24 01:02:05 -0700172 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face::FACEID_NULL, 101), CheckNextHopResult::NO_FIB_ENTRY);
Yanbiao Li711c7932015-08-19 16:30:16 -0700173}
174
175BOOST_AUTO_TEST_CASE(ImplicitFaceId)
176{
177 auto face1 = addFace();
178 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700179 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
180 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700181
182 Name expectedName;
183 ControlResponse expectedResponse;
184 auto testAddNextHop = [&] (ControlParameters parameters, const FaceId& faceId) {
185 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000186 [&faceId] (shared_ptr<Interest> interest) {
187 interest->setTag(make_shared<lp::IncomingFaceIdTag>(faceId));
188 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700189 m_responses.clear();
190 expectedName = command->getName();
191 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
192 receiveInterest(command);
193 };
194
195 testAddNextHop(ControlParameters().setName("/hello").setCost(100).setFaceId(0), face1);
196 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
197 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
198 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 100), CheckNextHopResult::OK);
199
200 testAddNextHop(ControlParameters().setName("/hello").setCost(100), face2);
201 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
202 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
203 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face2, 100), CheckNextHopResult::OK);
204}
205
206BOOST_AUTO_TEST_CASE(InitialAdd)
207{
208 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700209 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700210
211 auto parameters = makeParameters("hello", addedFaceId, 101);
212 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
213
214 receiveInterest(command);
215 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
216 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
217 CheckResponseResult::OK);
218 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 101), CheckNextHopResult::OK);
219}
220
221BOOST_AUTO_TEST_CASE(ImplicitCost)
222{
223 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700224 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700225
226 auto originalParameters = ControlParameters().setName("/hello").setFaceId(addedFaceId);
227 auto parameters = makeParameters("/hello", addedFaceId, 0);
228 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", originalParameters);
229
230 receiveInterest(command);
231 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
232 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
233 CheckResponseResult::OK);
234 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 0), CheckNextHopResult::OK);
235}
236
237BOOST_AUTO_TEST_CASE(AddToExisting)
238{
239 FaceId face = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700240 BOOST_REQUIRE_NE(face, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700241
242 Name expectedName;
243 ControlResponse expectedResponse;
244 auto testAddNextHop = [&] (const ControlParameters& parameters) {
245 m_responses.clear();
246 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
247 expectedName = command->getName();
248 expectedResponse = makeResponse(200, "Success", parameters);
249 receiveInterest(command);
250 };
251
252 // add initial, succeeds
253 testAddNextHop(makeParameters("/hello", face, 101));
254 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
255 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
256
257 // add to existing --> update cost, succeeds
258 testAddNextHop(makeParameters("/hello", face, 102));
259 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
260 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
261
262 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face, 102), CheckNextHopResult::WRONG_N_NEXTHOPS);
263 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 101), CheckNextHopResult::WRONG_COST);
264 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 102), CheckNextHopResult::OK);
265}
266
267BOOST_AUTO_TEST_SUITE_END() // AddNextHop
268
269BOOST_AUTO_TEST_SUITE(RemoveNextHop)
270
271BOOST_AUTO_TEST_CASE(Basic)
272{
273 Name expectedName;
274 ControlResponse expectedResponse;
275 auto testRemoveNextHop = [&] (const ControlParameters& parameters) {
276 m_responses.clear();
277 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
278 expectedName = command->getName();
279 expectedResponse = makeResponse(200, "Success", parameters);
280 receiveInterest(command);
281 };
282
283 FaceId face1 = addFace();
284 FaceId face2 = addFace();
285 FaceId face3 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700286 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
287 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
288 BOOST_REQUIRE_NE(face3, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700289
Junxiao Shia6de4292016-07-12 02:08:10 +0000290 fib::Entry* entry = m_fib.insert("/hello").first;
291 entry->addNextHop(*m_faceTable.get(face1), 101);
292 entry->addNextHop(*m_faceTable.get(face2), 202);
293 entry->addNextHop(*m_faceTable.get(face3), 303);
Yanbiao Li711c7932015-08-19 16:30:16 -0700294
295 testRemoveNextHop(makeParameters("/hello", face1));
296 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
297 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
298 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face1, 101), CheckNextHopResult::NO_NEXTHOP);
299
300 testRemoveNextHop(makeParameters("/hello", face2));
301 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
302 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
303 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face2, 202), CheckNextHopResult::NO_NEXTHOP);
304
305 testRemoveNextHop(makeParameters("/hello", face3));
306 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
307 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
308 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face3, 303), CheckNextHopResult::NO_FIB_ENTRY);
309}
310
311BOOST_AUTO_TEST_CASE(PrefixNotFound)
312{
313 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700314 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700315
316 auto parameters = makeParameters("hello", addedFaceId);
317 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
318 auto response = makeResponse(200, "Success", parameters);
319
320 receiveInterest(command);
321 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
322 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), response), CheckResponseResult::OK);
323}
324
325BOOST_AUTO_TEST_CASE(ImplicitFaceId)
326{
327 auto face1 = addFace();
328 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700329 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
330 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700331
332 Name expectedName;
333 ControlResponse expectedResponse;
334 auto testWithImplicitFaceId = [&] (ControlParameters parameters, FaceId face) {
335 m_responses.clear();
336 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000337 [face] (shared_ptr<Interest> interest) {
338 interest->setTag(make_shared<lp::IncomingFaceIdTag>(face));
339 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700340 expectedName = command->getName();
341 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
342 receiveInterest(command);
343 };
344
Junxiao Shia6de4292016-07-12 02:08:10 +0000345 fib::Entry* entry = m_fib.insert("/hello").first;
346 entry->addNextHop(*m_faceTable.get(face1), 101);
347 entry->addNextHop(*m_faceTable.get(face2), 202);
Yanbiao Li711c7932015-08-19 16:30:16 -0700348
349 testWithImplicitFaceId(ControlParameters().setName("/hello").setFaceId(0), face1);
350 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
351 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
352 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 101), CheckNextHopResult::NO_NEXTHOP);
353
354 testWithImplicitFaceId(ControlParameters().setName("/hello"), face2);
355 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
356 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
357 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face2, 202), CheckNextHopResult::NO_FIB_ENTRY);
358}
359
360BOOST_AUTO_TEST_CASE(RecordNotExist)
361{
362 auto face1 = addFace();
363 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700364 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
365 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700366
367 Name expectedName;
368 ControlResponse expectedResponse;
369 auto testRemoveNextHop = [&] (ControlParameters parameters) {
370 m_responses.clear();
371 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
372 expectedName = command->getName();
373 expectedResponse = makeResponse(200, "Success", parameters);
374 receiveInterest(command);
375 };
376
Junxiao Shia6de4292016-07-12 02:08:10 +0000377 m_fib.insert("/hello").first->addNextHop(*m_faceTable.get(face1), 101);
Yanbiao Li711c7932015-08-19 16:30:16 -0700378
379 testRemoveNextHop(makeParameters("/hello", face2 + 100));
380 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // face does not exist
381 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
382 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2 + 100), CheckNextHopResult::NO_NEXTHOP);
383
384 testRemoveNextHop(makeParameters("/hello", face2));
385 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // record does not exist
386 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
387 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2), CheckNextHopResult::NO_NEXTHOP);
388}
389
390BOOST_AUTO_TEST_SUITE_END() // RemoveNextHop
391
392// @todo Remove when ndn::nfd::FibEntry implements operator!= and operator<<
393class FibEntry : public ndn::nfd::FibEntry
394{
395public:
396 FibEntry() = default;
397
398 FibEntry(const ndn::nfd::FibEntry& entry)
399 : ndn::nfd::FibEntry(entry)
400 {
401 }
402};
403
404bool
405operator!=(const FibEntry& left, const FibEntry& right)
406{
407 if (left.getPrefix() != right.getPrefix()) {
408 return true;
409 }
410
411 auto leftNextHops = left.getNextHopRecords();
412 auto rightNextHops = right.getNextHopRecords();
413 if (leftNextHops.size() != rightNextHops.size()) {
414 return true;
415 }
416
417 for (auto&& nexthop : leftNextHops) {
418 auto hitEntry =
419 std::find_if(rightNextHops.begin(), rightNextHops.end(), [&] (const ndn::nfd::NextHopRecord& record) {
420 return nexthop.getCost() == record.getCost() && nexthop.getFaceId() == record.getFaceId();
421 });
422
423 if (hitEntry == rightNextHops.end()) {
424 return true;
425 }
426 }
427
428 return false;
429}
430
431std::ostream&
432operator<<(std::ostream &os, const FibEntry& entry)
433{
434 const auto& nexthops = entry.getNextHopRecords();
435 os << "[" << entry.getPrefix() << ", " << nexthops.size() << ": ";
436 for (auto record : nexthops) {
437 os << "{" << record.getFaceId() << ", " << record.getCost() << "} ";
438 }
439 os << "]";
440
441 return os;
442}
443
444BOOST_AUTO_TEST_CASE(FibDataset)
445{
446 const size_t nEntries = 108;
447 std::set<Name> actualPrefixes;
448 for (size_t i = 0 ; i < nEntries ; i ++) {
449 Name prefix = Name("test").appendSegment(i);
450 actualPrefixes.insert(prefix);
Junxiao Shia6de4292016-07-12 02:08:10 +0000451 fib::Entry* fibEntry = m_fib.insert(prefix).first;
452 fibEntry->addNextHop(*m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 1);
453 fibEntry->addNextHop(*m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 2);
Yanbiao Li711c7932015-08-19 16:30:16 -0700454 }
455
456 receiveInterest(makeInterest("/localhost/nfd/fib/list"));
457
458 Block content;
459 BOOST_CHECK_NO_THROW(content = concatenateResponses());
460 BOOST_CHECK_NO_THROW(content.parse());
461 BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
462
463 std::vector<FibEntry> receivedRecords, expectedRecords;
464 for (size_t idx = 0; idx < nEntries; ++idx) {
465 BOOST_TEST_MESSAGE("processing element: " << idx);
466
467 FibEntry decodedEntry;
468 BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
469 receivedRecords.push_back(decodedEntry);
470
471 actualPrefixes.erase(decodedEntry.getPrefix());
472
473 auto matchedEntry = m_fib.findExactMatch(decodedEntry.getPrefix());
474 BOOST_REQUIRE(matchedEntry != nullptr);
475
476 FibEntry record;
477 record.setPrefix(matchedEntry->getPrefix());
478 const auto& nextHops = matchedEntry->getNextHops();
479 for (auto&& next : nextHops) {
480 ndn::nfd::NextHopRecord nextHopRecord;
Junxiao Shia6de4292016-07-12 02:08:10 +0000481 nextHopRecord.setFaceId(next.getFace().getId());
Yanbiao Li711c7932015-08-19 16:30:16 -0700482 nextHopRecord.setCost(next.getCost());
483 record.addNextHopRecord(nextHopRecord);
484 }
485 expectedRecords.push_back(record);
486 }
487
488 BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
489
490 BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
491 expectedRecords.begin(), expectedRecords.end());
492}
493
494BOOST_AUTO_TEST_SUITE_END() // TestFibManager
495BOOST_AUTO_TEST_SUITE_END() // Mgmt
496
497} // namespace tests
498} // namespace nfd