blob: 68783992b4124feac8e7e09517ca129cdd9f4f2b [file] [log] [blame]
Yanbiao Li73860e32015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi0ba6d642017-07-17 00:53:22 +00002/*
Davide Pesavento1db1bb62025-01-06 01:23:41 -05003 * Copyright (c) 2014-2025, Regents of the University of California,
Yanbiao Li73860e32015-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
26#include "mgmt/face-manager.hpp"
Junxiao Shiea47bde2017-01-26 17:49:16 +000027#include "face/protocol-factory.hpp"
Yanbiao Li73860e32015-08-19 16:30:16 -070028
Davide Pesavento1d2d3372025-01-14 12:04:12 -050029#include "face-manager-command-fixture.hpp"
Davide Pesavento78ddcab2019-02-28 22:00:03 -050030#include "tests/daemon/face/dummy-face.hpp"
31#include "tests/daemon/face/dummy-transport.hpp"
Davide Pesavento97210d52016-10-14 15:45:48 +020032
Yanbiao Li73860e32015-08-19 16:30:16 -070033#include <ndn-cxx/encoding/tlv.hpp>
Davide Pesavento7a294d42017-02-21 21:46:44 -050034#include <ndn-cxx/encoding/tlv-nfd.hpp>
Junxiao Shi25c6ce42016-09-09 13:49:59 +000035#include <ndn-cxx/mgmt/nfd/channel-status.hpp>
Davide Pesavento28181322018-11-08 16:44:50 -050036#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
37#include <ndn-cxx/mgmt/nfd/face-query-filter.hpp>
38#include <ndn-cxx/mgmt/nfd/face-status.hpp>
Junxiao Shi0ba6d642017-07-17 00:53:22 +000039#include <ndn-cxx/net/network-monitor-stub.hpp>
Davide Pesaventob8bd5ee2019-02-03 22:53:40 -050040#include <ndn-cxx/util/random.hpp>
Yanbiao Li73860e32015-08-19 16:30:16 -070041
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040042namespace nfd::tests {
Yanbiao Li73860e32015-08-19 16:30:16 -070043
Davide Pesavento78ddcab2019-02-28 22:00:03 -050044class FaceManagerFixture : public ManagerFixtureWithAuthenticator
Yanbiao Li73860e32015-08-19 16:30:16 -070045{
Davide Pesavento4296fe32025-01-14 23:00:41 -050046protected:
Yanbiao Li73860e32015-08-19 16:30:16 -070047 FaceManagerFixture()
Davide Pesaventoa4abfb02019-10-06 16:02:56 -040048 : m_faceSystem(m_faceTable, make_shared<ndn::net::NetworkMonitorStub>(0))
Junxiao Shiea47bde2017-01-26 17:49:16 +000049 , m_manager(m_faceSystem, m_dispatcher, *m_authenticator)
Yanbiao Li73860e32015-08-19 16:30:16 -070050 {
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000051 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080052 setPrivilege("faces");
Yanbiao Li73860e32015-08-19 16:30:16 -070053 }
54
Junxiao Shicde37ad2015-12-24 01:02:05 -070055 enum AddFaceFlags {
56 REMOVE_LAST_NOTIFICATION = 1 << 0,
Davide Pesavento4296fe32025-01-14 23:00:41 -050057 RANDOMIZE_COUNTERS = 1 << 1,
Junxiao Shicde37ad2015-12-24 01:02:05 -070058 };
59
Davide Pesaventod7083a52023-10-19 17:51:16 -040060 /**
61 * \brief Adds a face to the FaceTable.
62 * \param flags bitwise OR'ed AddFaceFlags
Junxiao Shicde37ad2015-12-24 01:02:05 -070063 */
Davide Pesavento4296fe32025-01-14 23:00:41 -050064 template<typename... Args>
Yanbiao Li73860e32015-08-19 16:30:16 -070065 shared_ptr<Face>
Davide Pesavento2b43d672025-01-16 00:32:22 -050066 addFace(unsigned int flags, Args&&... args)
Yanbiao Li73860e32015-08-19 16:30:16 -070067 {
Davide Pesavento4296fe32025-01-14 23:00:41 -050068 auto face = make_shared<DummyFace>(std::forward<Args>(args)...);
Yanbiao Li73860e32015-08-19 16:30:16 -070069 m_faceTable.add(face);
Junxiao Shicde37ad2015-12-24 01:02:05 -070070
Davide Pesavento28181322018-11-08 16:44:50 -050071 if (flags & RANDOMIZE_COUNTERS) {
72 const auto& counters = face->getCounters();
Junxiao Shicde37ad2015-12-24 01:02:05 -070073 randomizeCounter(counters.nInInterests);
74 randomizeCounter(counters.nOutInterests);
75 randomizeCounter(counters.nInData);
76 randomizeCounter(counters.nOutData);
77 randomizeCounter(counters.nInNacks);
78 randomizeCounter(counters.nOutNacks);
79 randomizeCounter(counters.nInPackets);
80 randomizeCounter(counters.nOutPackets);
81 randomizeCounter(counters.nInBytes);
82 randomizeCounter(counters.nOutBytes);
83 }
84
Davide Pesavento28181322018-11-08 16:44:50 -050085 advanceClocks(1_ms, 10); // wait for notification posted
86 if (flags & REMOVE_LAST_NOTIFICATION) {
Davide Pesavento4296fe32025-01-14 23:00:41 -050087 BOOST_TEST_REQUIRE(!m_responses.empty());
Yanbiao Li73860e32015-08-19 16:30:16 -070088 m_responses.pop_back();
89 }
Junxiao Shicde37ad2015-12-24 01:02:05 -070090
Yanbiao Li73860e32015-08-19 16:30:16 -070091 return face;
92 }
93
Davide Pesavento2b43d672025-01-16 00:32:22 -050094 // We cannot combine this overload with the previous one
95 // because clang 10 (and earlier) doesn't like it.
96 // This is a workaround for https://github.com/llvm/llvm-project/issues/23403
97 shared_ptr<Face>
98 addFace()
99 {
100 return addFace(0);
101 }
102
Junxiao Shicde37ad2015-12-24 01:02:05 -0700103private:
104 template<typename T>
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400105 static void
Junxiao Shicde37ad2015-12-24 01:02:05 -0700106 randomizeCounter(const T& counter)
107 {
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200108 static std::uniform_int_distribution<typename T::rep> dist;
Davide Pesaventob8bd5ee2019-02-03 22:53:40 -0500109 const_cast<T&>(counter).set(dist(ndn::random::getRandomNumberEngine()));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700110 }
111
Yanbiao Li73860e32015-08-19 16:30:16 -0700112protected:
Junxiao Shiea47bde2017-01-26 17:49:16 +0000113 FaceSystem m_faceSystem;
Yanbiao Li73860e32015-08-19 16:30:16 -0700114 FaceManager m_manager;
115};
116
Davide Pesavento97210d52016-10-14 15:45:48 +0200117BOOST_AUTO_TEST_SUITE(Mgmt)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700118BOOST_FIXTURE_TEST_SUITE(TestFaceManager, FaceManagerFixture)
Yanbiao Li73860e32015-08-19 16:30:16 -0700119
120BOOST_AUTO_TEST_SUITE(DestroyFace)
121
122BOOST_AUTO_TEST_CASE(Existing)
123{
Davide Pesavento4296fe32025-01-14 23:00:41 -0500124 auto addedFace = addFace(REMOVE_LAST_NOTIFICATION); // clear notification for creation
Yanbiao Li73860e32015-08-19 16:30:16 -0700125
126 auto parameters = ControlParameters().setFaceId(addedFace->getId());
Davide Pesavento1d2d3372025-01-14 12:04:12 -0500127 auto req = makeControlCommandRequest(FaceManagerCommandFixture::DESTROY_REQUEST, parameters);
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000128 receiveInterest(req);
Yanbiao Li73860e32015-08-19 16:30:16 -0700129
130 BOOST_REQUIRE_EQUAL(m_responses.size(), 2); // one response and one notification
131 // notification is already tested, so ignore it
132
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000133 BOOST_CHECK_EQUAL(checkResponse(1, req.getName(), makeResponse(200, "OK", parameters)),
Yanbiao Li73860e32015-08-19 16:30:16 -0700134 CheckResponseResult::OK);
135
Junxiao Shicde37ad2015-12-24 01:02:05 -0700136 BOOST_CHECK_EQUAL(addedFace->getId(), face::INVALID_FACEID);
Yanbiao Li73860e32015-08-19 16:30:16 -0700137}
138
139BOOST_AUTO_TEST_CASE(NonExisting)
140{
141 auto parameters = ControlParameters().setFaceId(65535);
Davide Pesavento1d2d3372025-01-14 12:04:12 -0500142 auto req = makeControlCommandRequest(FaceManagerCommandFixture::DESTROY_REQUEST, parameters);
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000143 receiveInterest(req);
Yanbiao Li73860e32015-08-19 16:30:16 -0700144
145 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000146 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), makeResponse(200, "OK", parameters)),
Yanbiao Li73860e32015-08-19 16:30:16 -0700147 CheckResponseResult::OK);
148}
149
150BOOST_AUTO_TEST_SUITE_END() // DestroyFace
151
Davide Pesavento97210d52016-10-14 15:45:48 +0200152BOOST_AUTO_TEST_SUITE(Datasets)
Yanbiao Li73860e32015-08-19 16:30:16 -0700153
154BOOST_AUTO_TEST_CASE(FaceDataset)
155{
Davide Pesavento28181322018-11-08 16:44:50 -0500156 const size_t nEntries = 32;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700157 for (size_t i = 0; i < nEntries; ++i) {
Davide Pesavento4296fe32025-01-14 23:00:41 -0500158 addFace(REMOVE_LAST_NOTIFICATION | RANDOMIZE_COUNTERS, "test://", "test://");
Yanbiao Li73860e32015-08-19 16:30:16 -0700159 }
160
Davide Pesavento28181322018-11-08 16:44:50 -0500161 receiveInterest(Interest("/localhost/nfd/faces/list").setCanBePrefix(true));
Yanbiao Li73860e32015-08-19 16:30:16 -0700162
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400163 Block content = concatenateResponses();
164 content.parse();
Yanbiao Li73860e32015-08-19 16:30:16 -0700165 BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
166
Davide Pesavento4296fe32025-01-14 23:00:41 -0500167 std::unordered_set<FaceId> faceIds;
168 for (const auto& el : content.elements()) {
169 ndn::nfd::FaceStatus decodedStatus(el);
Davide Pesaventod7083a52023-10-19 17:51:16 -0400170 BOOST_TEST_INFO_SCOPE(decodedStatus);
Junxiao Shida93f1f2015-11-11 06:13:16 -0700171 BOOST_CHECK(m_faceTable.get(decodedStatus.getFaceId()) != nullptr);
Yanbiao Li73860e32015-08-19 16:30:16 -0700172 faceIds.insert(decodedStatus.getFaceId());
Yanbiao Li73860e32015-08-19 16:30:16 -0700173 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700174 BOOST_CHECK_EQUAL(faceIds.size(), nEntries);
Davide Pesavento28181322018-11-08 16:44:50 -0500175
176 ndn::nfd::FaceStatus status(content.elements().front());
177 const Face* face = m_faceTable.get(status.getFaceId());
Davide Pesavento4296fe32025-01-14 23:00:41 -0500178 BOOST_TEST_REQUIRE(face != nullptr);
Davide Pesavento28181322018-11-08 16:44:50 -0500179
180 // check face properties
181 BOOST_CHECK_EQUAL(status.getRemoteUri(), face->getRemoteUri().toString());
182 BOOST_CHECK_EQUAL(status.getLocalUri(), face->getLocalUri().toString());
Davide Pesavento4296fe32025-01-14 23:00:41 -0500183 BOOST_TEST(!status.hasExpirationPeriod());
184 BOOST_CHECK_EQUAL(status.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
185 BOOST_CHECK_EQUAL(status.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
186 BOOST_CHECK_EQUAL(status.getLinkType(), ndn::nfd::LINK_TYPE_POINT_TO_POINT);
Davide Pesavento28181322018-11-08 16:44:50 -0500187
188 // check link service properties
189 BOOST_CHECK_EQUAL(status.hasBaseCongestionMarkingInterval(), false);
190 BOOST_CHECK_EQUAL(status.hasDefaultCongestionThreshold(), false);
191 BOOST_CHECK_EQUAL(status.getFlags(), 0);
192
193 // check transport properties
Davide Pesavento4296fe32025-01-14 23:00:41 -0500194 BOOST_TEST_REQUIRE(status.hasMtu());
Davide Pesavento28181322018-11-08 16:44:50 -0500195 BOOST_CHECK_EQUAL(status.getMtu(), ndn::MAX_NDN_PACKET_SIZE);
196
197 // check counters
198 BOOST_CHECK_EQUAL(status.getNInInterests(), face->getCounters().nInInterests);
199 BOOST_CHECK_EQUAL(status.getNInData(), face->getCounters().nInData);
200 BOOST_CHECK_EQUAL(status.getNInNacks(), face->getCounters().nInNacks);
201 BOOST_CHECK_EQUAL(status.getNOutInterests(), face->getCounters().nOutInterests);
202 BOOST_CHECK_EQUAL(status.getNOutData(), face->getCounters().nOutData);
203 BOOST_CHECK_EQUAL(status.getNOutNacks(), face->getCounters().nOutNacks);
204 BOOST_CHECK_EQUAL(status.getNInBytes(), face->getCounters().nInBytes);
205 BOOST_CHECK_EQUAL(status.getNOutBytes(), face->getCounters().nOutBytes);
Yanbiao Li73860e32015-08-19 16:30:16 -0700206}
207
208BOOST_AUTO_TEST_CASE(FaceQuery)
209{
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400210 using ndn::nfd::FaceQueryFilter;
211
Davide Pesavento4296fe32025-01-14 23:00:41 -0500212 auto face1 = addFace(REMOVE_LAST_NOTIFICATION, "dummy://one", "dummy://one",
213 ndn::nfd::FACE_SCOPE_NON_LOCAL,
214 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
215 ndn::nfd::LINK_TYPE_POINT_TO_POINT);
216 auto face2 = addFace(REMOVE_LAST_NOTIFICATION, "dummy://two", "remote://foo",
217 ndn::nfd::FACE_SCOPE_LOCAL,
218 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
219 ndn::nfd::LINK_TYPE_POINT_TO_POINT);
220 auto face3 = addFace(REMOVE_LAST_NOTIFICATION, "local://bar", "remote://foo",
221 ndn::nfd::FACE_SCOPE_NON_LOCAL,
222 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
223 ndn::nfd::LINK_TYPE_POINT_TO_POINT);
224 auto face4 = addFace(REMOVE_LAST_NOTIFICATION, "local://bar", "dummy://four",
225 ndn::nfd::FACE_SCOPE_NON_LOCAL,
226 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
227 ndn::nfd::LINK_TYPE_AD_HOC);
Yanbiao Li73860e32015-08-19 16:30:16 -0700228
Davide Pesaventodeb54272022-03-11 18:51:05 -0500229 auto generateQuery = [] (const auto& filter) {
Davide Pesavento1db1bb62025-01-06 01:23:41 -0500230 return Interest(Name("/localhost/nfd/faces/query").append(filter.wireEncode()))
Davide Pesavento28181322018-11-08 16:44:50 -0500231 .setCanBePrefix(true);
Yanbiao Li73860e32015-08-19 16:30:16 -0700232 };
233
Davide Pesavento4296fe32025-01-14 23:00:41 -0500234 auto allQuery = generateQuery(FaceQueryFilter());
235 auto noneQuery = generateQuery(FaceQueryFilter().setUriScheme("nomatch"));
Davide Pesavento28181322018-11-08 16:44:50 -0500236 auto idQuery = generateQuery(FaceQueryFilter().setFaceId(face1->getId()));
Davide Pesavento4296fe32025-01-14 23:00:41 -0500237 auto schemeQuery = generateQuery(FaceQueryFilter().setUriScheme("dummy"));
238 auto remoteQuery = generateQuery(FaceQueryFilter().setRemoteUri("remote://foo"));
239 auto localQuery = generateQuery(FaceQueryFilter().setLocalUri("local://bar"));
240 auto scopeQuery = generateQuery(FaceQueryFilter().setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL));
241 auto persistencyQuery = generateQuery(FaceQueryFilter().setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT));
242 auto linkQuery = generateQuery(FaceQueryFilter().setLinkType(ndn::nfd::LINK_TYPE_AD_HOC));
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400243 auto invalidQueryName = Name("/localhost/nfd/faces/query")
Davide Pesavento1db1bb62025-01-06 01:23:41 -0500244 .append(ndn::makeStringBlock(tlv::Content, "invalid"));
Davide Pesavento28181322018-11-08 16:44:50 -0500245 auto invalidQuery = Interest(invalidQueryName).setCanBePrefix(true);
Yanbiao Li73860e32015-08-19 16:30:16 -0700246
Davide Pesavento4296fe32025-01-14 23:00:41 -0500247 receiveInterest(allQuery); // all 4 faces expected
248 receiveInterest(noneQuery); // no faces expected
Davide Pesavento28181322018-11-08 16:44:50 -0500249 receiveInterest(idQuery); // face1 expected
Davide Pesavento4296fe32025-01-14 23:00:41 -0500250 receiveInterest(schemeQuery); // face1, face2, face4 expected
251 receiveInterest(remoteQuery); // face2 and face3 expected
252 receiveInterest(localQuery); // face3 and face4 expected
253 receiveInterest(scopeQuery); // face2 expected
254 receiveInterest(persistencyQuery); // face3 expected
255 receiveInterest(linkQuery); // face4 expected
Davide Pesavento28181322018-11-08 16:44:50 -0500256 receiveInterest(invalidQuery); // nack expected
Yanbiao Li73860e32015-08-19 16:30:16 -0700257
Davide Pesavento4296fe32025-01-14 23:00:41 -0500258 BOOST_REQUIRE_EQUAL(m_responses.size(), 10);
Yanbiao Li73860e32015-08-19 16:30:16 -0700259
Davide Pesavento4296fe32025-01-14 23:00:41 -0500260 auto checkQueryResponse = [this] (size_t idx, const std::unordered_set<FaceId>& expected) {
261 BOOST_TEST_INFO("Response index = " << idx);
262 const Block& content = m_responses.at(idx).getContent();
263 content.parse();
264 std::unordered_set<FaceId> actual;
265 std::string actualStr;
266 for (const auto& el : content.elements()) {
267 ndn::nfd::FaceStatus status(el);
268 actual.insert(status.getFaceId());
269 actualStr += std::to_string(status.getFaceId()) + " ";
270 }
271 BOOST_TEST_INFO("Content = { " << actualStr << "}");
272 BOOST_TEST(actual == expected);
273 };
Yanbiao Li73860e32015-08-19 16:30:16 -0700274
Davide Pesavento4296fe32025-01-14 23:00:41 -0500275 checkQueryResponse(0, {face1->getId(), face2->getId(), face3->getId(), face4->getId()});
276 checkQueryResponse(1, {});
277 checkQueryResponse(2, {face1->getId()});
278 checkQueryResponse(3, {face1->getId(), face2->getId(), face4->getId()});
279 checkQueryResponse(4, {face2->getId(), face3->getId()});
280 checkQueryResponse(5, {face3->getId(), face4->getId()});
281 checkQueryResponse(6, {face2->getId()});
282 checkQueryResponse(7, {face3->getId()});
283 checkQueryResponse(8, {face4->getId()});
Yanbiao Li73860e32015-08-19 16:30:16 -0700284
Davide Pesavento4296fe32025-01-14 23:00:41 -0500285 // nack, 400, malformed filter
286 ControlResponse expectedResponse(400, "Malformed filter");
287 BOOST_CHECK_EQUAL(checkResponse(9, invalidQueryName, expectedResponse, tlv::ContentType_Nack),
Yanbiao Li73860e32015-08-19 16:30:16 -0700288 CheckResponseResult::OK);
289}
290
Davide Pesavento8fd15e62017-04-06 19:58:54 -0400291class TestChannel : public face::Channel
Yanbiao Li73860e32015-08-19 16:30:16 -0700292{
293public:
Davide Pesavento97210d52016-10-14 15:45:48 +0200294 explicit
Yanbiao Li73860e32015-08-19 16:30:16 -0700295 TestChannel(const std::string& uri)
296 {
297 setUri(FaceUri(uri));
298 }
Davide Pesaventoc19408d2017-04-08 00:42:55 -0400299
300 bool
301 isListening() const final
302 {
303 return false;
304 }
305
306 size_t
307 size() const final
308 {
309 return 0;
310 }
Yanbiao Li73860e32015-08-19 16:30:16 -0700311};
312
Davide Pesaventoe5eebad2017-04-06 20:23:26 -0400313class TestProtocolFactory : public face::ProtocolFactory
Yanbiao Li73860e32015-08-19 16:30:16 -0700314{
315public:
Davide Pesaventod27841b2018-11-13 00:22:24 -0500316 using ProtocolFactory::ProtocolFactory;
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000317
Yanbiao Li73860e32015-08-19 16:30:16 -0700318 shared_ptr<TestChannel>
319 addChannel(const std::string& channelUri)
320 {
321 auto channel = make_shared<TestChannel>(channelUri);
322 m_channels.push_back(channel);
323 return channel;
324 }
325
326private:
Davide Pesaventod27841b2018-11-13 00:22:24 -0500327 std::vector<shared_ptr<const face::Channel>>
328 doGetChannels() const final
329 {
330 return m_channels;
331 }
332
333private:
Davide Pesavento8fd15e62017-04-06 19:58:54 -0400334 std::vector<shared_ptr<const face::Channel>> m_channels;
Yanbiao Li73860e32015-08-19 16:30:16 -0700335};
336
337BOOST_AUTO_TEST_CASE(ChannelDataset)
338{
Davide Pesavento28181322018-11-08 16:44:50 -0500339 m_faceSystem.m_factories["test"] = make_unique<TestProtocolFactory>(m_faceSystem.makePFCtorParams());
Davide Pesaventob5eee202017-09-21 23:59:22 -0400340 auto factory = static_cast<TestProtocolFactory*>(m_faceSystem.getFactoryById("test"));
Yanbiao Li73860e32015-08-19 16:30:16 -0700341
Davide Pesavento28181322018-11-08 16:44:50 -0500342 const size_t nEntries = 42;
Yanbiao Li73860e32015-08-19 16:30:16 -0700343 std::map<std::string, shared_ptr<TestChannel>> addedChannels;
Eric Newberry1b4ba052016-10-07 23:04:07 -0700344 for (size_t i = 0; i < nEntries; i++) {
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -0500345 auto channel = factory->addChannel("test" + std::to_string(i) + "://");
Yanbiao Li73860e32015-08-19 16:30:16 -0700346 addedChannels[channel->getUri().toString()] = channel;
347 }
348
Davide Pesavento28181322018-11-08 16:44:50 -0500349 receiveInterest(Interest("/localhost/nfd/faces/channels").setCanBePrefix(true));
Yanbiao Li73860e32015-08-19 16:30:16 -0700350
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400351 Block content = concatenateResponses();
352 content.parse();
Yanbiao Li73860e32015-08-19 16:30:16 -0700353 BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
354
Davide Pesavento4296fe32025-01-14 23:00:41 -0500355 for (const auto& el : content.elements()) {
356 ndn::nfd::ChannelStatus decodedStatus(el);
Davide Pesaventod7083a52023-10-19 17:51:16 -0400357 BOOST_TEST_INFO_SCOPE(decodedStatus);
Davide Pesavento4296fe32025-01-14 23:00:41 -0500358 BOOST_TEST(addedChannels.count(decodedStatus.getLocalUri()) == 1);
Yanbiao Li73860e32015-08-19 16:30:16 -0700359 }
360}
361
Davide Pesavento97210d52016-10-14 15:45:48 +0200362BOOST_AUTO_TEST_SUITE_END() // Datasets
363
364BOOST_AUTO_TEST_SUITE(Notifications)
365
Eric Newberry1b4ba052016-10-07 23:04:07 -0700366BOOST_AUTO_TEST_CASE(FaceEventCreated)
Davide Pesavento97210d52016-10-14 15:45:48 +0200367{
Eric Newberry1b4ba052016-10-07 23:04:07 -0700368 auto face = addFace(); // trigger FACE_EVENT_CREATED notification
369 BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
370 FaceId faceId = face->getId();
371
372 BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 1);
Davide Pesavento97210d52016-10-14 15:45:48 +0200373
374 // check notification
Eric Newberry1b4ba052016-10-07 23:04:07 -0700375 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400376 Block payload = m_responses.back().getContent().blockFromValue();
Eric Newberry1b4ba052016-10-07 23:04:07 -0700377 BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400378 ndn::nfd::FaceEventNotification notification(payload);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700379 BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
380 BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
381 BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
382 BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
383 BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
384 BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
385 BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400386 BOOST_CHECK_EQUAL(notification.getFlags(), 0);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700387}
Davide Pesavento97210d52016-10-14 15:45:48 +0200388
Eric Newberry1b4ba052016-10-07 23:04:07 -0700389BOOST_AUTO_TEST_CASE(FaceEventDownUp)
390{
391 auto face = addFace();
392 BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
393 FaceId faceId = face->getId();
394
395 // trigger FACE_EVENT_DOWN notification
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400396 dynamic_cast<DummyTransport*>(face->getTransport())->setState(face::FaceState::DOWN);
Davide Pesavento28181322018-11-08 16:44:50 -0500397 advanceClocks(1_ms, 10);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700398 BOOST_CHECK_EQUAL(face->getState(), face::FaceState::DOWN);
Davide Pesavento97210d52016-10-14 15:45:48 +0200399
400 // check notification
401 {
Davide Pesavento97210d52016-10-14 15:45:48 +0200402 BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400403 Block payload = m_responses.back().getContent().blockFromValue();
Davide Pesavento97210d52016-10-14 15:45:48 +0200404 BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400405 ndn::nfd::FaceEventNotification notification(payload);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700406 BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DOWN);
Davide Pesavento97210d52016-10-14 15:45:48 +0200407 BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700408 BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
409 BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
Davide Pesavento97210d52016-10-14 15:45:48 +0200410 BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
411 BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
412 BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400413 BOOST_CHECK_EQUAL(notification.getFlags(), 0);
Davide Pesavento97210d52016-10-14 15:45:48 +0200414 }
Eric Newberry1b4ba052016-10-07 23:04:07 -0700415
416 // trigger FACE_EVENT_UP notification
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400417 dynamic_cast<DummyTransport*>(face->getTransport())->setState(face::FaceState::UP);
Davide Pesavento28181322018-11-08 16:44:50 -0500418 advanceClocks(1_ms, 10);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700419 BOOST_CHECK_EQUAL(face->getState(), face::FaceState::UP);
420
421 // check notification
422 {
Eric Newberry1b4ba052016-10-07 23:04:07 -0700423 BOOST_REQUIRE_EQUAL(m_responses.size(), 3);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400424 Block payload = m_responses.back().getContent().blockFromValue();
Eric Newberry1b4ba052016-10-07 23:04:07 -0700425 BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400426 ndn::nfd::FaceEventNotification notification(payload);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700427 BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_UP);
428 BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
429 BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
430 BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
431 BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
432 BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
433 BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400434 BOOST_CHECK_EQUAL(notification.getFlags(), 0);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700435 }
436}
437
438BOOST_AUTO_TEST_CASE(FaceEventDestroyed)
439{
440 auto face = addFace();
441 BOOST_CHECK_NE(face->getId(), face::INVALID_FACEID);
442 FaceId faceId = face->getId();
443
444 BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 1);
445
446 face->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
Davide Pesavento28181322018-11-08 16:44:50 -0500447 advanceClocks(1_ms, 10);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700448
449 // check notification
Eric Newberry1b4ba052016-10-07 23:04:07 -0700450 BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400451 Block payload = m_responses.back().getContent().blockFromValue();
Eric Newberry1b4ba052016-10-07 23:04:07 -0700452 BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400453 ndn::nfd::FaceEventNotification notification(payload);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700454 BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
455 BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
456 BOOST_CHECK_EQUAL(notification.getRemoteUri(), face->getRemoteUri().toString());
457 BOOST_CHECK_EQUAL(notification.getLocalUri(), face->getLocalUri().toString());
458 BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
459 BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
460 BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
Davide Pesavento6837d4f2017-07-15 13:01:03 -0400461 BOOST_CHECK_EQUAL(notification.getFlags(), 0);
Eric Newberry1b4ba052016-10-07 23:04:07 -0700462
463 BOOST_CHECK_EQUAL(face->getId(), face::INVALID_FACEID);
464 BOOST_CHECK_EQUAL(m_manager.m_faceStateChangeConn.count(faceId), 0);
Davide Pesavento97210d52016-10-14 15:45:48 +0200465}
466
467BOOST_AUTO_TEST_SUITE_END() // Notifications
468
Yanbiao Li73860e32015-08-19 16:30:16 -0700469BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
470BOOST_AUTO_TEST_SUITE_END() // Mgmt
471
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400472} // namespace nfd::tests