tests: expand test coverage of EthernetFactory and UdpFactory
Change-Id: I469ac8682502ca7a0e360703b462bfb119eaedf1
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 9ffd16e..1908cac 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -271,13 +271,13 @@
return nullptr;
}
- if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
- NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
+ if (!netif->isUp()) {
+ NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
return nullptr;
}
- if (!netif->isUp()) {
- NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": netif is down");
+ if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
+ NFD_LOG_DEBUG("Not creating channel on " << netif->getName() << ": incompatible netif type");
return nullptr;
}
@@ -305,18 +305,13 @@
return nullptr;
}
- if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
- NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
- return nullptr;
- }
-
if (!netif.isUp()) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif is down");
return nullptr;
}
- if (!netif.canMulticast()) {
- NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
+ if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
+ NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": incompatible netif type");
return nullptr;
}
@@ -325,6 +320,11 @@
return nullptr;
}
+ if (!netif.canMulticast()) {
+ NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": netif cannot multicast");
+ return nullptr;
+ }
+
if (!m_mcastConfig.netifPredicate(netif)) {
NFD_LOG_DEBUG("Not creating multicast face on " << netif.getName() << ": rejected by whitelist/blacklist");
return nullptr;
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 0ee4562..d09c7df 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -39,11 +39,6 @@
, public FaceSystemFactoryFixture<EthernetFactory>
{
protected:
- EthernetFactoryFixture()
- {
- this->copyRealNetifsToNetmon();
- }
-
std::set<std::string>
listUrisOfAvailableNetifs() const
{
@@ -59,17 +54,37 @@
return listFacesByScheme("ether", linkType);
}
- size_t
- countEtherMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
+ shared_ptr<ndn::net::NetworkInterface>
+ makeFakeNetif()
{
- return listEtherMcastFaces(linkType).size();
+ static int counter = 0;
+ ++counter;
+
+ auto netif = netmon->makeNetworkInterface();
+ netif->setIndex(1000 + counter);
+ netif->setName("ethdummy" + std::to_string(counter));
+ netif->setType(ndn::net::InterfaceType::ETHERNET);
+ netif->setFlags(IFF_MULTICAST | IFF_UP);
+ netif->setState(ndn::net::InterfaceState::RUNNING);
+ netif->setMtu(1500);
+ netif->setEthernetAddress(ethernet::Address{0x00, 0x00, 0x5e, 0x00, 0x53, 0x5e});
+ return netif;
+ }
+};
+
+class EthernetFactoryFixtureWithRealNetifs : public EthernetFactoryFixture
+{
+protected:
+ EthernetFactoryFixtureWithRealNetifs()
+ {
+ copyRealNetifsToNetmon();
}
};
BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestEthernetFactory, EthernetFactoryFixture)
+BOOST_AUTO_TEST_SUITE(TestEthernetFactory)
-BOOST_AUTO_TEST_SUITE(ProcessConfig)
+BOOST_FIXTURE_TEST_SUITE(ProcessConfig, EthernetFactoryFixtureWithRealNetifs)
BOOST_AUTO_TEST_CASE(Defaults)
{
@@ -79,9 +94,6 @@
face_system
{
ether
- {
- mcast no
- }
}
)CONFIG";
@@ -92,10 +104,10 @@
auto channels = factory.getChannels();
BOOST_CHECK(std::all_of(channels.begin(), channels.end(),
[] (const auto& ch) { return ch->isListening(); }));
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), netifs.size());
}
-BOOST_AUTO_TEST_CASE(DisableListen)
+BOOST_AUTO_TEST_CASE(DisableListenAndMcast)
{
SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
@@ -118,13 +130,11 @@
auto channels = factory.getChannels();
BOOST_CHECK(std::none_of(channels.begin(), channels.end(),
[] (const auto& ch) { return ch->isListening(); }));
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
}
BOOST_AUTO_TEST_CASE(McastNormal)
{
- SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
-
const std::string CONFIG = R"CONFIG(
face_system
{
@@ -148,8 +158,9 @@
parseConfig(CONFIG, true);
parseConfig(CONFIG, false);
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), netifs.size());
- for (const auto& face : this->listEtherMcastFaces()) {
+ auto etherMcastFaces = this->listEtherMcastFaces();
+ BOOST_CHECK_EQUAL(etherMcastFaces.size(), netifs.size());
+ for (const auto* face : etherMcastFaces) {
BOOST_REQUIRE(face->getChannel().lock());
// not universal, but for Ethernet, local URI of a mcast face matches URI of the associated channel
BOOST_CHECK_EQUAL(face->getLocalUri(), face->getChannel().lock()->getUri());
@@ -180,17 +191,17 @@
)CONFIG";
parseConfig(CONFIG_WITHOUT_MCAST, false);
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
parseConfig(CONFIG_WITH_MCAST, false);
g_io.poll();
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), netifs.size());
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), netifs.size());
parseConfig(CONFIG_WITHOUT_MCAST, false);
g_io.poll();
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
}
BOOST_AUTO_TEST_CASE(McastAdHoc)
@@ -203,15 +214,14 @@
ether
{
listen no
- mcast yes
mcast_ad_hoc yes
}
}
)CONFIG";
parseConfig(CONFIG, false);
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS), 0);
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifs.size());
}
BOOST_AUTO_TEST_CASE(ChangeMcastGroup)
@@ -238,6 +248,7 @@
)CONFIG";
parseConfig(CONFIG1, false);
+ g_io.poll();
auto etherMcastFaces = this->listEtherMcastFaces();
BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), netifs.size());
BOOST_CHECK_EQUAL(etherMcastFaces.front()->getRemoteUri(),
@@ -317,7 +328,7 @@
parseConfig(CONFIG, true);
parseConfig(CONFIG, false);
- BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
}
BOOST_AUTO_TEST_CASE(BadListen)
@@ -432,7 +443,7 @@
BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
-BOOST_AUTO_TEST_CASE(GetChannels)
+BOOST_FIXTURE_TEST_CASE(GetChannels, EthernetFactoryFixtureWithRealNetifs)
{
BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
@@ -442,22 +453,23 @@
checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
}
-BOOST_AUTO_TEST_CASE(CreateChannel)
+BOOST_FIXTURE_TEST_CASE(CreateChannel, EthernetFactoryFixtureWithRealNetifs)
{
SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
auto channel1 = factory.createChannel(netifs.front(), 1_min);
auto channel1a = factory.createChannel(netifs.front(), 5_min);
BOOST_CHECK_EQUAL(channel1, channel1a);
- BOOST_CHECK_EQUAL(channel1->getUri().toString(), "dev://" + netifs.front()->getName());
+ checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
SKIP_IF_ETHERNET_NETIF_COUNT_LT(2);
auto channel2 = factory.createChannel(netifs.back(), 1_min);
BOOST_CHECK_NE(channel1, channel2);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
}
-BOOST_AUTO_TEST_CASE(CreateFace)
+BOOST_FIXTURE_TEST_CASE(CreateFace, EthernetFactoryFixtureWithRealNetifs)
{
createFace(factory,
FaceUri("ether://[00:00:5e:00:53:5e]"),
@@ -505,7 +517,7 @@
{CreateFaceExpectedResult::SUCCESS, 0, ""});
}
-BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
+BOOST_FIXTURE_TEST_CASE(CreateFaceInvalidRequest, EthernetFactoryFixture)
{
createFace(factory,
FaceUri("ether://[00:00:5e:00:53:5e]"),
@@ -541,8 +553,119 @@
{ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
{CreateFaceExpectedResult::FAILURE, 406,
"Local fields can only be enabled on faces with local scope"});
+
+ createFace(factory,
+ FaceUri("ether://[00:00:5e:00:53:5e]"),
+ FaceUri("dev://eth0"),
+ {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 42, false, false, false},
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Override MTU cannot be less than 64"});
}
+BOOST_FIXTURE_TEST_SUITE(OnInterfaceAdded, EthernetFactoryFixture)
+
+BOOST_AUTO_TEST_CASE(EligibleForChannelAndMcast)
+{
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ ether
+ }
+ )CONFIG", false);
+ g_io.poll();
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+
+ // Add a fake interface that satisfies both unicast and multicast criteria.
+ netmon->addInterface(this->makeFakeNetif());
+ // The channel fails to listen because the interface is fake.
+ // However, it's not removed from the channel list (issue #4400).
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
+ // Multicast face creation fails because the interface is fake.
+ // This test is to ensure that the factory handles failures gracefully.
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+
+ SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+ // Now add a real interface: both channel and multicast face should be created successfully.
+ netmon->addInterface(const_pointer_cast<ndn::net::NetworkInterface>(netifs.front()));
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
+ auto etherMcastFaces = this->listEtherMcastFaces();
+ BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), 1);
+ BOOST_CHECK_EQUAL(etherMcastFaces.front()->getLocalUri(), FaceUri::fromDev(netifs.front()->getName()));
+}
+
+BOOST_AUTO_TEST_CASE(EligibleForChannelOnly)
+{
+ SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ ether
+ {
+ listen no
+ }
+ }
+ )CONFIG", false);
+ g_io.poll();
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+
+ // Add an interface that satisfies only the unicast criteria.
+ auto netif = const_pointer_cast<ndn::net::NetworkInterface>(netifs.front());
+ netif->setFlags(netif->getFlags() & ~IFF_MULTICAST);
+ netmon->addInterface(netif);
+ checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Ineligible)
+{
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ ether
+ }
+ )CONFIG", false);
+ g_io.poll();
+
+ // netif is down
+ auto netif = this->makeFakeNetif();
+ netif->setFlags(netif->getFlags() & ~IFF_UP);
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+
+ // incompatible netif type
+ netif = this->makeFakeNetif();
+ netif->setType(ndn::net::InterfaceType::LOOPBACK);
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+
+ // invalid Ethernet address
+ netif = this->makeFakeNetif();
+ netif->setEthernetAddress(ethernet::Address{});
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Disabled)
+{
+ SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+ parseConfig("", false);
+ g_io.poll();
+
+ netmon->addInterface(const_pointer_cast<ndn::net::NetworkInterface>(netifs.front()));
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
+ BOOST_CHECK_EQUAL(this->listEtherMcastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // OnInterfaceAdded
+
BOOST_AUTO_TEST_SUITE_END() // TestEthernetFactory
BOOST_AUTO_TEST_SUITE_END() // Face
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index e2aa73d..d7c6a67 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -350,13 +350,16 @@
auto channel1a = createChannel("127.0.0.1", "20070");
BOOST_CHECK_EQUAL(channel1, channel1a);
BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
auto channel2 = createChannel("127.0.0.1", "20071");
BOOST_CHECK_NE(channel1, channel2);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
auto channel3 = createChannel("::1", "20071");
BOOST_CHECK_NE(channel2, channel3);
BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 3);
}
BOOST_AUTO_TEST_CASE(CreateFace)
@@ -400,10 +403,8 @@
{CreateFaceExpectedResult::SUCCESS, 0, ""});
}
-BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
+BOOST_AUTO_TEST_CASE(CreateFaceInvalidRequest)
{
- createChannel("127.0.0.1", "20071");
-
createFace(factory,
FaceUri("tcp4://127.0.0.1:20072"),
FaceUri("tcp4://127.0.0.1:20071"),
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index fd83656..55d601c 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -32,6 +32,7 @@
namespace nfd::tests {
+namespace ip = boost::asio::ip;
using face::UdpChannel;
using face::UdpFactory;
using ndn::net::NetworkInterface;
@@ -42,7 +43,7 @@
shared_ptr<UdpChannel>
createChannel(const std::string& localIp, uint16_t localPort)
{
- udp::Endpoint endpoint(boost::asio::ip::make_address(localIp), localPort);
+ udp::Endpoint endpoint(ip::make_address(localIp), localPort);
return factory.createChannel(endpoint, 5_min);
}
};
@@ -53,7 +54,7 @@
UdpFactoryMcastFixture()
{
for (const auto& netif : collectNetworkInterfaces()) {
- // same filtering logic as UdpFactory::applyMcastConfigToNetif()
+ // similar filtering logic to UdpFactory::applyMcastConfigToNetif()
if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
bool hasValidIpAddress = false;
if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
@@ -69,38 +70,6 @@
}
}
}
- copyRealNetifsToNetmon();
- }
-
- shared_ptr<Face>
- createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
- {
- auto localAddress = boost::asio::ip::make_address(localIp);
- udp::Endpoint mcastEndpoint(boost::asio::ip::make_address(mcastIp), mcastPort);
-
- if (localAddress.is_v4()) {
- BOOST_ASSERT(!netifsV4.empty());
- return factory.createMulticastFace(*netifsV4.front(), localAddress, mcastEndpoint);
- }
- else {
- BOOST_ASSERT(!netifsV6.empty());
- return factory.createMulticastFace(*netifsV6.front(), localAddress, mcastEndpoint);
- }
- }
-
- /** \brief Returns a non-loopback IP address suitable for the creation of a UDP multicast face.
- */
- boost::asio::ip::address
- findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
- {
- const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
- for (const auto& netif : netifList) {
- for (const auto& a : netif->getNetworkAddresses()) {
- if (a.getFamily() == af && !a.getIp().is_loopback())
- return a.getIp();
- }
- }
- return {};
}
std::vector<const Face*>
@@ -115,6 +84,35 @@
return listFacesByScheme("udp6", linkType);
}
+ shared_ptr<NetworkInterface>
+ makeFakeNetif(bool addNetworkAddresses = true)
+ {
+ using namespace ndn::net;
+
+ static int counter = 0;
+ ++counter;
+
+ auto netif = netmon->makeNetworkInterface();
+ netif->setIndex(1000 + counter);
+ netif->setName("ethdummy" + std::to_string(counter));
+ netif->setType(InterfaceType::ETHERNET);
+ netif->setFlags(IFF_MULTICAST | IFF_UP);
+ netif->setState(InterfaceState::RUNNING);
+ netif->setMtu(1500);
+ netif->setEthernetAddress(ethernet::Address{0x3e, 0x15, 0xc2, 0x8b, 0x65, 0x00});
+ if (addNetworkAddresses) {
+ netif->addNetworkAddress(NetworkAddress(AddressFamily::V4,
+ ip::make_address_v4("192.168.2.1"),
+ ip::make_address_v4("192.168.2.255"),
+ 24, AddressScope::GLOBAL, 0));
+ netif->addNetworkAddress(NetworkAddress(AddressFamily::V6,
+ ip::make_address_v6("2001:db8:2::1"),
+ ip::make_address_v6("2001:db8:2::ffff:ffff:ffff:ffff"),
+ 64, AddressScope::GLOBAL, 0));
+ }
+ return netif;
+ }
+
/**
* \brief Determine whether \p netif has at least one IP address of the given family.
*/
@@ -131,9 +129,9 @@
static bool
isFaceOnNetif(const Face& face, const NetworkInterface& netif)
{
- auto ip = boost::asio::ip::make_address(face.getLocalUri().getHost());
+ auto faceIp = ip::make_address(face.getLocalUri().getHost());
return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
- [ip] (const auto& a) { return a.getIp() == ip; });
+ [faceIp] (const auto& a) { return a.getIp() == faceIp; });
}
protected:
@@ -152,6 +150,47 @@
std::vector<shared_ptr<const NetworkInterface>> netifsV6;
};
+class UdpFactoryMcastFixtureWithRealNetifs : public UdpFactoryMcastFixture
+{
+protected:
+ UdpFactoryMcastFixtureWithRealNetifs()
+ {
+ copyRealNetifsToNetmon();
+ }
+
+ shared_ptr<Face>
+ createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
+ {
+ auto localAddress = ip::make_address(localIp);
+ udp::Endpoint mcastEndpoint(ip::make_address(mcastIp), mcastPort);
+
+ if (localAddress.is_v4()) {
+ BOOST_ASSERT(!netifsV4.empty());
+ return factory.createMulticastFace(*netifsV4.front(), localAddress, mcastEndpoint);
+ }
+ else {
+ BOOST_ASSERT(!netifsV6.empty());
+ return factory.createMulticastFace(*netifsV6.front(), localAddress, mcastEndpoint);
+ }
+ }
+
+ /**
+ * \brief Returns a non-loopback IP address suitable for the creation of a UDP multicast face.
+ */
+ ip::address
+ findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
+ {
+ const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
+ for (const auto& netif : netifList) {
+ for (const auto& a : netif->getNetworkAddresses()) {
+ if (a.getFamily() == af && !a.getIp().is_loopback())
+ return a.getIp();
+ }
+ }
+ return {};
+ }
+};
+
#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
do { \
if (this->netifs.size() < (n)) { \
@@ -180,11 +219,9 @@
} while (false)
BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
+BOOST_AUTO_TEST_SUITE(TestUdpFactory)
-BOOST_AUTO_TEST_SUITE(ProcessConfig)
-
-using nfd::Face;
+BOOST_FIXTURE_TEST_SUITE(ProcessConfig, UdpFactoryFixture)
BOOST_AUTO_TEST_CASE(Defaults)
{
@@ -278,7 +315,7 @@
}
}
-BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixtureWithRealNetifs)
{
const std::string CONFIG_WITH_MCAST = R"CONFIG(
face_system
@@ -313,13 +350,13 @@
BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());
- BOOST_REQUIRE_EQUAL(factory.getChannels().size(), 2);
- for (const auto& face : this->listUdp4McastFaces()) {
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
+ for (const auto* face : this->listUdp4McastFaces()) {
BOOST_REQUIRE(face->getChannel().lock());
BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
}
- for (const auto& face : this->listUdp6McastFaces()) {
+ for (const auto* face : this->listUdp6McastFaces()) {
BOOST_REQUIRE(face->getChannel().lock());
BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
}
@@ -330,7 +367,7 @@
BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
}
-BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -349,11 +386,13 @@
)CONFIG";
parseConfig(CONFIG, false);
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
}
-BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -383,6 +422,7 @@
)CONFIG";
parseConfig(CONFIG1, false);
+ g_io.poll();
auto udpMcastFaces = this->listUdp4McastFaces();
BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));
@@ -394,7 +434,7 @@
BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
}
-BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -424,14 +464,15 @@
)CONFIG";
parseConfig(CONFIG1, false);
+ g_io.poll();
auto udpMcastFaces = this->listUdp6McastFaces();
BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
auto uri = udpMcastFaces.front()->getRemoteUri();
BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
// check the address ignoring the scope id
- auto addr = boost::asio::ip::make_address_v6(uri.getHost());
+ auto addr = ip::make_address_v6(uri.getHost());
addr.scope_id(0);
- BOOST_CHECK_EQUAL(addr, boost::asio::ip::make_address_v6("ff02::1101"));
+ BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1101"));
BOOST_CHECK_EQUAL(uri.getPort(), "7011");
parseConfig(CONFIG2, false);
@@ -441,13 +482,13 @@
uri = udpMcastFaces.front()->getRemoteUri();
BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
// check the address ignoring the scope id
- addr = boost::asio::ip::make_address_v6(uri.getHost());
+ addr = ip::make_address_v6(uri.getHost());
addr.scope_id(0);
- BOOST_CHECK_EQUAL(addr, boost::asio::ip::make_address_v6("ff02::1102"));
+ BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1102"));
BOOST_CHECK_EQUAL(uri.getPort(), "7012");
}
-BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -478,10 +519,10 @@
udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
BOOST_CHECK_GE(udpMcastFaces.size(), 1);
BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
- [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
+ [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
}
-BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -514,10 +555,10 @@
udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
- [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
+ [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
}
-BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -542,13 +583,14 @@
boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
parseConfig(CONFIG1, false);
+ g_io.poll();
auto udpMcastFaces = this->listUdp4McastFaces();
auto udpMcastFacesV6 = this->listUdp6McastFaces();
udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
BOOST_CHECK_GE(udpMcastFaces.size(), 1);
BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
- [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.front()); }));
+ [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
parseConfig(CONFIG2, false);
g_io.poll();
@@ -558,7 +600,7 @@
udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
BOOST_CHECK_GE(udpMcastFaces.size(), 1);
BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
- [this] (const Face* face) { return isFaceOnNetif(*face, *netifs.back()); }));
+ [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.back()); }));
}
BOOST_AUTO_TEST_CASE(Omitted)
@@ -914,7 +956,7 @@
BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
-BOOST_AUTO_TEST_CASE(GetChannels)
+BOOST_FIXTURE_TEST_CASE(GetChannels, UdpFactoryFixture)
{
BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
@@ -925,47 +967,49 @@
checkChannelListEqual(factory, expected);
}
-BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixtureWithRealNetifs)
{
auto channel1 = createChannel("127.0.0.1", 20070);
auto channel1a = createChannel("127.0.0.1", 20070);
BOOST_CHECK_EQUAL(channel1, channel1a);
BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
auto channel2 = createChannel("127.0.0.1", 20071);
BOOST_CHECK_NE(channel1, channel2);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
auto channel3 = createChannel("::1", 20071);
BOOST_CHECK_NE(channel2, channel3);
BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 3);
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
+ SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
// createChannel with a local endpoint that has already been allocated to a UDP multicast face
if (!netifsV4.empty()) {
auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP channel on 127.0.0.1:20072, "
- "endpoint already allocated to a UDP multicast face") == 0;
+ return e.what() == "Cannot create UDP channel on 127.0.0.1:20072, "
+ "endpoint already allocated to a UDP multicast face"s;
});
}
if (!netifsV6.empty()) {
auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP channel on [::1]:20072, "
- "endpoint already allocated to a UDP multicast face") == 0;
+ return e.what() == "Cannot create UDP channel on [::1]:20072, "
+ "endpoint already allocated to a UDP multicast face"s;
});
}
}
-BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -990,21 +1034,19 @@
auto channel = createChannel("127.0.0.1", 20071);
BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP multicast face on 127.0.0.1:20071, "
- "endpoint already allocated to a UDP channel") == 0;
+ return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20071, "
+ "endpoint already allocated to a UDP channel"s;
});
// create with a local endpoint already used by a multicast face on a different multicast group
BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP multicast face on 127.0.0.1:20070, "
- "endpoint already allocated to a different UDP multicast face") == 0;
+ return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20070, "
+ "endpoint already allocated to a different UDP multicast face"s;
});
}
-BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixture)
+BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
// need superuser privileges to create multicast faces on Linux
@@ -1029,21 +1071,19 @@
auto channel = createChannel("::1", 20071);
BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP multicast face on [::1]:20071, "
- "endpoint already allocated to a UDP channel") == 0;
+ return e.what() == "Cannot create UDP multicast face on [::1]:20071, "
+ "endpoint already allocated to a UDP channel"s;
});
// create with a local endpoint already used by a multicast face on a different multicast group
BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
[] (const UdpFactory::Error& e) {
- return strcmp(e.what(),
- "Cannot create UDP multicast face on [::1]:20070, "
- "endpoint already allocated to a different UDP multicast face") == 0;
+ return e.what() == "Cannot create UDP multicast face on [::1]:20070, "
+ "endpoint already allocated to a different UDP multicast face"s;
});
}
-BOOST_AUTO_TEST_CASE(CreateFace)
+BOOST_FIXTURE_TEST_CASE(CreateFace, UdpFactoryFixture)
{
createFace(factory,
FaceUri("udp4://127.0.0.1:6363"),
@@ -1090,10 +1130,8 @@
{CreateFaceExpectedResult::SUCCESS, 0, ""});
}
-BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
+BOOST_FIXTURE_TEST_CASE(CreateFaceInvalidRequest, UdpFactoryFixture)
{
- createChannel("127.0.0.1", 20071);
-
createFace(factory,
FaceUri("udp4://127.0.0.1:20072"),
FaceUri("udp4://127.0.0.1:20071"),
@@ -1121,8 +1159,132 @@
{ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
{CreateFaceExpectedResult::FAILURE, 406,
"Local fields can only be enabled on faces with local scope"});
+
+ createFace(factory,
+ FaceUri("udp4://127.0.0.1:20072"),
+ {},
+ {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 42, false, false, false},
+ {CreateFaceExpectedResult::FAILURE, 406,
+ "Override MTU cannot be less than 64"});
}
+BOOST_FIXTURE_TEST_SUITE(OnInterfaceAdded, UdpFactoryMcastFixture)
+
+BOOST_AUTO_TEST_CASE(EligibleV4)
+{
+#ifdef __linux__
+ // need superuser privileges to create multicast faces on Linux
+ SKIP_IF_NOT_SUPERUSER();
+#endif // __linux__
+ SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);
+
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ udp
+ }
+ )CONFIG", false);
+ g_io.poll();
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+
+ netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV4.front()));
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 1);
+ BOOST_CHECK_LE(this->listUdp6McastFaces().size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(EligibleV6)
+{
+#ifdef __linux__
+ // need superuser privileges to create multicast faces on Linux
+ SKIP_IF_NOT_SUPERUSER();
+#endif // __linux__
+ SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);
+
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ udp
+ }
+ )CONFIG", false);
+ g_io.poll();
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+
+ netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV6.front()));
+ BOOST_CHECK_LE(this->listUdp4McastFaces().size(), 1);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(EligibleFailure)
+{
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ udp
+ }
+ )CONFIG", false);
+ g_io.poll();
+
+ // Add a fake interface that satisfies the multicast criteria.
+ netmon->addInterface(this->makeFakeNetif());
+ // Creation of multicast faces fails because the interface does not actually exist.
+ // This test is to ensure that the factory handles failures gracefully.
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Ineligible)
+{
+ parseConfig(R"CONFIG(
+ face_system
+ {
+ udp
+ }
+ )CONFIG", false);
+ g_io.poll();
+
+ // netif is down
+ auto netif = this->makeFakeNetif();
+ netif->setFlags(netif->getFlags() & ~IFF_UP);
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+
+ // netif is loopback
+ netif = this->makeFakeNetif();
+ netif->setFlags(netif->getFlags() | IFF_LOOPBACK);
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+
+ // netif cannot multicast
+ netif = this->makeFakeNetif();
+ netif->setFlags(netif->getFlags() & ~IFF_MULTICAST);
+ netmon->addInterface(netif);
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+
+ // no viable IP address
+ netmon->addInterface(this->makeFakeNetif(false));
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(Disabled)
+{
+ SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
+
+ parseConfig("", false);
+ g_io.poll();
+
+ netmon->addInterface(const_pointer_cast<NetworkInterface>(netifs.front()));
+ BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
+ BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // OnInterfaceAdded
+
BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
BOOST_AUTO_TEST_SUITE_END() // Face
diff --git a/tests/daemon/face/unix-stream-factory.t.cpp b/tests/daemon/face/unix-stream-factory.t.cpp
index 2554b25..53a8687 100644
--- a/tests/daemon/face/unix-stream-factory.t.cpp
+++ b/tests/daemon/face/unix-stream-factory.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, Regents of the University of California,
+ * Copyright (c) 2014-2023, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -110,6 +110,7 @@
auto channel1 = factory.createChannel(CHANNEL_PATH1);
auto channel1a = factory.createChannel(CHANNEL_PATH1);
BOOST_CHECK_EQUAL(channel1, channel1a);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
const auto& uri = channel1->getUri();
BOOST_CHECK_EQUAL(uri.getScheme(), "unix");
@@ -119,9 +120,10 @@
auto channel2 = factory.createChannel(CHANNEL_PATH2);
BOOST_CHECK_NE(channel1, channel2);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
}
-BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
+BOOST_AUTO_TEST_CASE(CreateFace)
{
createFace(factory,
FaceUri("unix:///var/run/nfd.sock"),
diff --git a/tests/daemon/face/websocket-factory.t.cpp b/tests/daemon/face/websocket-factory.t.cpp
index c133671..b5104ea 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -286,16 +286,19 @@
auto channel1a = createChannel("127.0.0.1", "20070");
BOOST_CHECK_EQUAL(channel1, channel1a);
BOOST_CHECK_EQUAL(channel1->getUri().toString(), "ws://127.0.0.1:20070");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);
auto channel2 = createChannel("127.0.0.1", "20071");
BOOST_CHECK_NE(channel1, channel2);
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
auto channel3 = createChannel("::1", "20071");
BOOST_CHECK_NE(channel2, channel3);
BOOST_CHECK_EQUAL(channel3->getUri().toString(), "ws://[::1]:20071");
+ BOOST_CHECK_EQUAL(factory.getChannels().size(), 3);
}
-BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
+BOOST_AUTO_TEST_CASE(CreateFace)
{
createFace(factory,
FaceUri("ws://127.0.0.1:20070"),