blob: 87856ed359d27aaed66b5a0b5d3a1d8d38919894 [file] [log] [blame]
Yanbiao Li711c7932015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * 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
27#include "manager-common-fixture.hpp"
28#include "table/fib-nexthop.hpp"
29#include "../face/dummy-face.hpp"
30#include <ndn-cxx/management/nfd-fib-entry.hpp>
31
32namespace nfd {
33namespace tests {
34
35class FibManagerFixture : public ManagerCommonFixture
36{
37public:
38 FibManagerFixture()
39 : m_fib(m_forwarder.getFib())
40 , m_faceTable(m_forwarder.getFaceTable())
41 , m_manager(m_fib, bind(&Forwarder::getFace, &m_forwarder, _1), m_dispatcher, m_validator)
42 {
43 setTopPrefixAndPrivilege("/localhost/nfd", "fib");
44 }
45
46public: // for test
47 ControlParameters
48 makeParameters(const Name& name, const FaceId& id)
49 {
50 return ControlParameters().setName(name).setFaceId(id);
51 }
52
53 ControlParameters
54 makeParameters(const Name& name, const FaceId& id, const uint32_t& cost)
55 {
56 return ControlParameters().setName(name).setFaceId(id).setCost(cost);
57 }
58
59 FaceId
60 addFace()
61 {
62 auto face = make_shared<DummyFace>();
63 m_faceTable.add(face);
64 advanceClocks(time::milliseconds(1), 10);
65 m_responses.clear(); // clear all event notifications, if any
66 return face->getId();
67 }
68
69public: // for check
70 enum class CheckNextHopResult
71 {
72 OK,
73 NO_FIB_ENTRY,
74 WRONG_N_NEXTHOPS,
75 NO_NEXTHOP,
76 WRONG_COST
77 };
78
79 /**
80 * @brief check whether the nexthop record is added / removed properly
81 *
82 * @param expectedNNextHops use -1 to skip this check
Junxiao Shicde37ad2015-12-24 01:02:05 -070083 * @param faceId use face::FACEID_NULL to skip NextHopRecord checks
Yanbiao Li711c7932015-08-19 16:30:16 -070084 * @param expectedCost use -1 to skip this check
85 *
86 * @retval OK FIB entry is found by exact match and has the expected number of nexthops;
87 * NextHopRe record for faceId is found and has the expected cost
88 * @retval NO_FIB_ENTRY FIB entry is not found
89 * @retval WRONG_N_NEXTHOPS FIB entry is found but has wrong number of nexthops
90 * @retval NO_NEXTHOP NextHopRecord for faceId is not found
91 * @retval WRONG_COST NextHopRecord for faceId has wrong cost
92 */
93 CheckNextHopResult
94 checkNextHop(const Name& prefix, ssize_t expectedNNextHops = -1,
Junxiao Shicde37ad2015-12-24 01:02:05 -070095 FaceId faceId = face::FACEID_NULL, int32_t expectedCost = -1)
Yanbiao Li711c7932015-08-19 16:30:16 -070096 {
97 auto entry = m_fib.findExactMatch(prefix);
98 if (!static_cast<bool>(entry)) {
99 return CheckNextHopResult::NO_FIB_ENTRY;
100 }
101
102 auto nextHops = entry->getNextHops();
103 if (expectedNNextHops != -1 && nextHops.size() != static_cast<size_t>(expectedNNextHops)) {
104 return CheckNextHopResult::WRONG_N_NEXTHOPS;
105 }
106
Junxiao Shicde37ad2015-12-24 01:02:05 -0700107 if (faceId != face::FACEID_NULL) {
Yanbiao Li711c7932015-08-19 16:30:16 -0700108 for (auto&& record : nextHops) {
109 if (record.getFace()->getId() == faceId) {
110 return expectedCost != -1 && record.getCost() != static_cast<uint32_t>(expectedCost) ?
111 CheckNextHopResult::WRONG_COST : CheckNextHopResult::OK;
112 }
113 }
114
115 return CheckNextHopResult::NO_NEXTHOP;
116 }
117
118 return CheckNextHopResult::OK;
119 }
120
121protected:
122 Fib& m_fib;
123 FaceTable& m_faceTable;
124 FibManager m_manager;
125};
126
127std::ostream&
128operator<<(std::ostream &os, const FibManagerFixture::CheckNextHopResult& result)
129{
130 switch (result) {
131 case FibManagerFixture::CheckNextHopResult::OK:
132 os << "OK";
133 break;
134 case FibManagerFixture::CheckNextHopResult::NO_FIB_ENTRY:
135 os << "NO_FIB_ENTRY";
136 break;
137 case FibManagerFixture::CheckNextHopResult::WRONG_N_NEXTHOPS:
138 os << "WRONG_N_NEXTHOPS";
139 break;
140 case FibManagerFixture::CheckNextHopResult::NO_NEXTHOP:
141 os << "NO_NEXTHOP";
142 break;
143 case FibManagerFixture::CheckNextHopResult::WRONG_COST:
144 os << "WRONG_COST";
145 break;
146 default:
147 break;
148 };
149
150 return os;
151}
152
153BOOST_FIXTURE_TEST_SUITE(Mgmt, FibManagerFixture)
154BOOST_AUTO_TEST_SUITE(TestFibManager)
155
156BOOST_AUTO_TEST_SUITE(AddNextHop)
157
158BOOST_AUTO_TEST_CASE(UnknownFaceId)
159{
160 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop",
Junxiao Shicde37ad2015-12-24 01:02:05 -0700161 makeParameters("hello", face::FACEID_NULL, 101));
Yanbiao Li711c7932015-08-19 16:30:16 -0700162 receiveInterest(command);
163 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
164
165 // check response
166 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), ControlResponse(410, "Face not found")),
167 CheckResponseResult::OK);
168
169 // double check that the next hop was not added
Junxiao Shicde37ad2015-12-24 01:02:05 -0700170 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face::FACEID_NULL, 101), CheckNextHopResult::NO_FIB_ENTRY);
Yanbiao Li711c7932015-08-19 16:30:16 -0700171}
172
173BOOST_AUTO_TEST_CASE(ImplicitFaceId)
174{
175 auto face1 = addFace();
176 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700177 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
178 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700179
180 Name expectedName;
181 ControlResponse expectedResponse;
182 auto testAddNextHop = [&] (ControlParameters parameters, const FaceId& faceId) {
183 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000184 [&faceId] (shared_ptr<Interest> interest) {
185 interest->setTag(make_shared<lp::IncomingFaceIdTag>(faceId));
186 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700187 m_responses.clear();
188 expectedName = command->getName();
189 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
190 receiveInterest(command);
191 };
192
193 testAddNextHop(ControlParameters().setName("/hello").setCost(100).setFaceId(0), face1);
194 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
195 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
196 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 100), CheckNextHopResult::OK);
197
198 testAddNextHop(ControlParameters().setName("/hello").setCost(100), face2);
199 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
200 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
201 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face2, 100), CheckNextHopResult::OK);
202}
203
204BOOST_AUTO_TEST_CASE(InitialAdd)
205{
206 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700207 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700208
209 auto parameters = makeParameters("hello", addedFaceId, 101);
210 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
211
212 receiveInterest(command);
213 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
214 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
215 CheckResponseResult::OK);
216 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 101), CheckNextHopResult::OK);
217}
218
219BOOST_AUTO_TEST_CASE(ImplicitCost)
220{
221 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700222 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700223
224 auto originalParameters = ControlParameters().setName("/hello").setFaceId(addedFaceId);
225 auto parameters = makeParameters("/hello", addedFaceId, 0);
226 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", originalParameters);
227
228 receiveInterest(command);
229 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
230 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
231 CheckResponseResult::OK);
232 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 0), CheckNextHopResult::OK);
233}
234
235BOOST_AUTO_TEST_CASE(AddToExisting)
236{
237 FaceId face = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700238 BOOST_REQUIRE_NE(face, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700239
240 Name expectedName;
241 ControlResponse expectedResponse;
242 auto testAddNextHop = [&] (const ControlParameters& parameters) {
243 m_responses.clear();
244 auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
245 expectedName = command->getName();
246 expectedResponse = makeResponse(200, "Success", parameters);
247 receiveInterest(command);
248 };
249
250 // add initial, succeeds
251 testAddNextHop(makeParameters("/hello", face, 101));
252 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
253 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
254
255 // add to existing --> update cost, succeeds
256 testAddNextHop(makeParameters("/hello", face, 102));
257 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
258 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
259
260 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face, 102), CheckNextHopResult::WRONG_N_NEXTHOPS);
261 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 101), CheckNextHopResult::WRONG_COST);
262 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 102), CheckNextHopResult::OK);
263}
264
265BOOST_AUTO_TEST_SUITE_END() // AddNextHop
266
267BOOST_AUTO_TEST_SUITE(RemoveNextHop)
268
269BOOST_AUTO_TEST_CASE(Basic)
270{
271 Name expectedName;
272 ControlResponse expectedResponse;
273 auto testRemoveNextHop = [&] (const ControlParameters& parameters) {
274 m_responses.clear();
275 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
276 expectedName = command->getName();
277 expectedResponse = makeResponse(200, "Success", parameters);
278 receiveInterest(command);
279 };
280
281 FaceId face1 = addFace();
282 FaceId face2 = addFace();
283 FaceId face3 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700284 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
285 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
286 BOOST_REQUIRE_NE(face3, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700287
288 shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
289 entry->addNextHop(m_faceTable.get(face1), 101);
290 entry->addNextHop(m_faceTable.get(face2), 202);
291 entry->addNextHop(m_faceTable.get(face3), 303);
292
293 testRemoveNextHop(makeParameters("/hello", face1));
294 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
295 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
296 BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face1, 101), CheckNextHopResult::NO_NEXTHOP);
297
298 testRemoveNextHop(makeParameters("/hello", face2));
299 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
300 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
301 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face2, 202), CheckNextHopResult::NO_NEXTHOP);
302
303 testRemoveNextHop(makeParameters("/hello", face3));
304 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
305 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
306 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face3, 303), CheckNextHopResult::NO_FIB_ENTRY);
307}
308
309BOOST_AUTO_TEST_CASE(PrefixNotFound)
310{
311 FaceId addedFaceId = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700312 BOOST_REQUIRE_NE(addedFaceId, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700313
314 auto parameters = makeParameters("hello", addedFaceId);
315 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
316 auto response = makeResponse(200, "Success", parameters);
317
318 receiveInterest(command);
319 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
320 BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), response), CheckResponseResult::OK);
321}
322
323BOOST_AUTO_TEST_CASE(ImplicitFaceId)
324{
325 auto face1 = addFace();
326 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700327 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
328 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700329
330 Name expectedName;
331 ControlResponse expectedResponse;
332 auto testWithImplicitFaceId = [&] (ControlParameters parameters, FaceId face) {
333 m_responses.clear();
334 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters,
Junxiao Shi0de23a22015-12-03 20:07:02 +0000335 [face] (shared_ptr<Interest> interest) {
336 interest->setTag(make_shared<lp::IncomingFaceIdTag>(face));
337 });
Yanbiao Li711c7932015-08-19 16:30:16 -0700338 expectedName = command->getName();
339 expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
340 receiveInterest(command);
341 };
342
343 shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
344 entry->addNextHop(m_faceTable.get(face1), 101);
345 entry->addNextHop(m_faceTable.get(face2), 202);
346
347 testWithImplicitFaceId(ControlParameters().setName("/hello").setFaceId(0), face1);
348 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
349 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
350 BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 101), CheckNextHopResult::NO_NEXTHOP);
351
352 testWithImplicitFaceId(ControlParameters().setName("/hello"), face2);
353 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
354 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
355 BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face2, 202), CheckNextHopResult::NO_FIB_ENTRY);
356}
357
358BOOST_AUTO_TEST_CASE(RecordNotExist)
359{
360 auto face1 = addFace();
361 auto face2 = addFace();
Junxiao Shicde37ad2015-12-24 01:02:05 -0700362 BOOST_REQUIRE_NE(face1, face::INVALID_FACEID);
363 BOOST_REQUIRE_NE(face2, face::INVALID_FACEID);
Yanbiao Li711c7932015-08-19 16:30:16 -0700364
365 Name expectedName;
366 ControlResponse expectedResponse;
367 auto testRemoveNextHop = [&] (ControlParameters parameters) {
368 m_responses.clear();
369 auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
370 expectedName = command->getName();
371 expectedResponse = makeResponse(200, "Success", parameters);
372 receiveInterest(command);
373 };
374
375 m_fib.insert("/hello").first->addNextHop(m_faceTable.get(face1), 101);
376
377 testRemoveNextHop(makeParameters("/hello", face2 + 100));
378 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // face does not exist
379 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
380 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2 + 100), CheckNextHopResult::NO_NEXTHOP);
381
382 testRemoveNextHop(makeParameters("/hello", face2));
383 BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // record does not exist
384 BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
385 BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2), CheckNextHopResult::NO_NEXTHOP);
386}
387
388BOOST_AUTO_TEST_SUITE_END() // RemoveNextHop
389
390// @todo Remove when ndn::nfd::FibEntry implements operator!= and operator<<
391class FibEntry : public ndn::nfd::FibEntry
392{
393public:
394 FibEntry() = default;
395
396 FibEntry(const ndn::nfd::FibEntry& entry)
397 : ndn::nfd::FibEntry(entry)
398 {
399 }
400};
401
402bool
403operator!=(const FibEntry& left, const FibEntry& right)
404{
405 if (left.getPrefix() != right.getPrefix()) {
406 return true;
407 }
408
409 auto leftNextHops = left.getNextHopRecords();
410 auto rightNextHops = right.getNextHopRecords();
411 if (leftNextHops.size() != rightNextHops.size()) {
412 return true;
413 }
414
415 for (auto&& nexthop : leftNextHops) {
416 auto hitEntry =
417 std::find_if(rightNextHops.begin(), rightNextHops.end(), [&] (const ndn::nfd::NextHopRecord& record) {
418 return nexthop.getCost() == record.getCost() && nexthop.getFaceId() == record.getFaceId();
419 });
420
421 if (hitEntry == rightNextHops.end()) {
422 return true;
423 }
424 }
425
426 return false;
427}
428
429std::ostream&
430operator<<(std::ostream &os, const FibEntry& entry)
431{
432 const auto& nexthops = entry.getNextHopRecords();
433 os << "[" << entry.getPrefix() << ", " << nexthops.size() << ": ";
434 for (auto record : nexthops) {
435 os << "{" << record.getFaceId() << ", " << record.getCost() << "} ";
436 }
437 os << "]";
438
439 return os;
440}
441
442BOOST_AUTO_TEST_CASE(FibDataset)
443{
444 const size_t nEntries = 108;
445 std::set<Name> actualPrefixes;
446 for (size_t i = 0 ; i < nEntries ; i ++) {
447 Name prefix = Name("test").appendSegment(i);
448 actualPrefixes.insert(prefix);
449 auto fibEntry = m_fib.insert(prefix).first;
450 fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 1);
451 fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 2);
452 }
453
454 receiveInterest(makeInterest("/localhost/nfd/fib/list"));
455
456 Block content;
457 BOOST_CHECK_NO_THROW(content = concatenateResponses());
458 BOOST_CHECK_NO_THROW(content.parse());
459 BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
460
461 std::vector<FibEntry> receivedRecords, expectedRecords;
462 for (size_t idx = 0; idx < nEntries; ++idx) {
463 BOOST_TEST_MESSAGE("processing element: " << idx);
464
465 FibEntry decodedEntry;
466 BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
467 receivedRecords.push_back(decodedEntry);
468
469 actualPrefixes.erase(decodedEntry.getPrefix());
470
471 auto matchedEntry = m_fib.findExactMatch(decodedEntry.getPrefix());
472 BOOST_REQUIRE(matchedEntry != nullptr);
473
474 FibEntry record;
475 record.setPrefix(matchedEntry->getPrefix());
476 const auto& nextHops = matchedEntry->getNextHops();
477 for (auto&& next : nextHops) {
478 ndn::nfd::NextHopRecord nextHopRecord;
479 nextHopRecord.setFaceId(next.getFace()->getId());
480 nextHopRecord.setCost(next.getCost());
481 record.addNextHopRecord(nextHopRecord);
482 }
483 expectedRecords.push_back(record);
484 }
485
486 BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
487
488 BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
489 expectedRecords.begin(), expectedRecords.end());
490}
491
492BOOST_AUTO_TEST_SUITE_END() // TestFibManager
493BOOST_AUTO_TEST_SUITE_END() // Mgmt
494
495} // namespace tests
496} // namespace nfd