tests: improve EthernetFactory test coverage

Also simplify other factories' GetChannels test case
by using checkChannelListEqual().

Change-Id: I02ecbd06fad498ea84b11d32b61ed4d63d929f2d
Refs: #4012
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 27a2489..5e942d2 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -29,6 +29,7 @@
 #include "ethernet-fixture.hpp"
 #include "face-system-fixture.hpp"
 #include "factory-test-common.hpp"
+
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/range/algorithm/count_if.hpp>
 
@@ -45,6 +46,17 @@
     this->copyRealNetifsToNetmon();
   }
 
+  std::set<std::string>
+  listUrisOfAvailableNetifs() const
+  {
+    std::set<std::string> uris;
+    std::transform(netifs.begin(), netifs.end(), std::inserter(uris, uris.end()),
+                   [] (const shared_ptr<const ndn::net::NetworkInterface>& ni) {
+                     return FaceUri::fromDev(ni->getName()).toString();
+                   });
+    return uris;
+  }
+
   std::vector<const Face*>
   listEtherMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
   {
@@ -65,7 +77,7 @@
 
 BOOST_AUTO_TEST_SUITE(ProcessConfig)
 
-BOOST_AUTO_TEST_CASE(Normal)
+BOOST_AUTO_TEST_CASE(ListeningChannels)
 {
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
 
@@ -74,6 +86,79 @@
     {
       ether
       {
+        listen yes
+        idle_timeout 60
+        mcast no
+      }
+    }
+  )CONFIG";
+
+  parseConfig(CONFIG, true);
+  parseConfig(CONFIG, false);
+
+  auto& factory = this->getFactoryById<EthernetFactory>("ether");
+  checkChannelListEqual(factory, this->listUrisOfAvailableNetifs());
+  for (const auto& channel : factory.getChannels()) {
+    BOOST_CHECK_EQUAL(channel->isListening(), true);
+  }
+
+  BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(NonListeningChannels)
+{
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+  const std::string CONFIG = R"CONFIG(
+    face_system
+    {
+      ether
+      {
+        listen no
+        idle_timeout 60
+        mcast no
+      }
+    }
+  )CONFIG";
+
+  parseConfig(CONFIG, true);
+  parseConfig(CONFIG, false);
+
+  auto& factory = this->getFactoryById<EthernetFactory>("ether");
+  checkChannelListEqual(factory, this->listUrisOfAvailableNetifs());
+  for (const auto& channel : factory.getChannels()) {
+    BOOST_CHECK_EQUAL(channel->isListening(), false);
+  }
+
+  BOOST_CHECK_EQUAL(this->countEtherMcastFaces(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(BadListen)
+{
+  const std::string CONFIG = R"CONFIG(
+    face_system
+    {
+      ether
+      {
+        listen hello
+      }
+    }
+  )CONFIG";
+
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(McastNormal)
+{
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+  const std::string CONFIG = R"CONFIG(
+    face_system
+    {
+      ether
+      {
+        listen no
         mcast yes
         mcast_group 01:00:5E:00:17:AA
         mcast_ad_hoc no
@@ -101,6 +186,7 @@
     {
       ether
       {
+        listen no
         mcast yes
       }
     }
@@ -110,6 +196,7 @@
     {
       ether
       {
+        listen no
         mcast no
       }
     }
@@ -138,12 +225,15 @@
     {
       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());
 }
 
@@ -200,12 +290,14 @@
       }
     }
   )CONFIG";
-  boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
+  auto ifname = netifs.front()->getName();
+  boost::replace_first(CONFIG, "%ifname", ifname);
 
   parseConfig(CONFIG, false);
+
   auto etherMcastFaces = this->listEtherMcastFaces();
   BOOST_REQUIRE_EQUAL(etherMcastFaces.size(), 1);
-  BOOST_CHECK_EQUAL(etherMcastFaces.front()->getLocalUri().getHost(), netifs.front()->getName());
+  BOOST_CHECK_EQUAL(etherMcastFaces.front()->getLocalUri(), FaceUri::fromDev(ifname));
 }
 
 BOOST_AUTO_TEST_CASE(Blacklist)
@@ -224,13 +316,15 @@
       }
     }
   )CONFIG";
-  boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
+  auto ifname = netifs.front()->getName();
+  boost::replace_first(CONFIG, "%ifname", ifname);
 
   parseConfig(CONFIG, false);
+
   auto etherMcastFaces = this->listEtherMcastFaces();
   BOOST_CHECK_EQUAL(etherMcastFaces.size(), netifs.size() - 1);
-  BOOST_CHECK_EQUAL(boost::count_if(etherMcastFaces, [=] (const Face* face) {
-    return face->getLocalUri().getHost() == netifs.front()->getName();
+  BOOST_CHECK_EQUAL(boost::count_if(etherMcastFaces, [ifname] (const Face* face) {
+    return face->getLocalUri() == FaceUri::fromDev(ifname);
   }), 0);
 }
 
@@ -318,11 +412,63 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  auto channels = factory.getChannels();
-  BOOST_CHECK_EQUAL(channels.empty(), true);
+  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+  factory.createChannel(netifs.front(), time::minutes(1));
+  checkChannelListEqual(factory, {FaceUri::fromDev(netifs.front()->getName()).toString()});
 }
 
-BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
+BOOST_AUTO_TEST_CASE(CreateChannel)
+{
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+
+  auto channel1 = factory.createChannel(netifs.front(), time::minutes(1));
+  auto channel1a = factory.createChannel(netifs.front(), time::minutes(5));
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  BOOST_CHECK_EQUAL(channel1->getUri().toString(), "dev://" + netifs.front()->getName());
+
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(2);
+
+  auto channel2 = factory.createChannel(netifs.back(), time::minutes(1));
+  BOOST_CHECK_NE(channel1, channel2);
+}
+
+BOOST_AUTO_TEST_CASE(CreateFace)
+{
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:5e]"),
+             FaceUri("dev://eth0"),
+             ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+             false,
+             {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
+
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+  auto localUri = factory.createChannel(netifs.front(), time::minutes(1))->getUri();
+
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:5e]"),
+             localUri,
+             ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:5e]"),
+             localUri,
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:53]"),
+             localUri,
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+}
+
+BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
 {
   createFace(factory,
              FaceUri("ether://[00:00:5e:00:53:5e]"),
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index e00e984..f6307d6 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -25,8 +25,8 @@
 
 #include "face/tcp-factory.hpp"
 
-#include "factory-test-common.hpp"
 #include "face-system-fixture.hpp"
+#include "factory-test-common.hpp"
 #include "tests/limited-io.hpp"
 
 namespace nfd {
@@ -129,39 +129,33 @@
 
 BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
 
-BOOST_AUTO_TEST_CASE(ChannelMap)
+BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  shared_ptr<TcpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
-  shared_ptr<TcpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
+  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
+
+  std::set<std::string> expected;
+  expected.insert(factory.createChannel("127.0.0.1", "20070")->getUri().toString());
+  expected.insert(factory.createChannel("127.0.0.1", "20071")->getUri().toString());
+  expected.insert(factory.createChannel("::1", "20071")->getUri().toString());
+  checkChannelListEqual(factory, expected);
+}
+
+BOOST_AUTO_TEST_CASE(CreateChannel)
+{
+  auto channel1 = factory.createChannel("127.0.0.1", "20070");
+  auto channel1a = factory.createChannel("127.0.0.1", "20070");
   BOOST_CHECK_EQUAL(channel1, channel1a);
   BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
 
-  shared_ptr<TcpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  auto channel2 = factory.createChannel("127.0.0.1", "20071");
   BOOST_CHECK_NE(channel1, channel2);
 
-  shared_ptr<TcpChannel> channel3 = factory.createChannel("::1", "20071");
+  auto channel3 = factory.createChannel("::1", "20071");
   BOOST_CHECK_NE(channel2, channel3);
   BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
 }
 
-BOOST_AUTO_TEST_CASE(GetChannels)
-{
-  BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
-
-  std::vector<shared_ptr<const Channel>> expectedChannels;
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
-  expectedChannels.push_back(factory.createChannel("::1", "20071"));
-
-  for (const auto& ch : factory.getChannels()) {
-    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), ch);
-    BOOST_REQUIRE(pos != expectedChannels.end());
-    expectedChannels.erase(pos);
-  }
-  BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
-}
-
-BOOST_AUTO_TEST_CASE(FaceCreate)
+BOOST_AUTO_TEST_CASE(CreateFace)
 {
   createFace(factory,
              FaceUri("tcp4://127.0.0.1:6363"),
@@ -194,7 +188,7 @@
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
-BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
+BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
 {
   factory.createChannel("127.0.0.1", "20071");
 
@@ -223,7 +217,7 @@
               "Local fields can only be enabled on faces with local scope"});
 }
 
-class FaceCreateTimeoutFixture : public TcpFactoryFixture
+class CreateFaceTimeoutFixture : public TcpFactoryFixture
 {
 public:
   void
@@ -248,14 +242,14 @@
   shared_ptr<Face> face;
 };
 
-BOOST_FIXTURE_TEST_CASE(FaceCreateTimeout, FaceCreateTimeoutFixture)
+BOOST_FIXTURE_TEST_CASE(CreateFaceTimeout, CreateFaceTimeoutFixture)
 {
   factory.createChannel("0.0.0.0", "20070");
 
   factory.createFace({FaceUri("tcp4://192.0.2.1:20070"), {},
                       ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false},
-                     bind(&FaceCreateTimeoutFixture::onFaceCreated, this, _1),
-                     bind(&FaceCreateTimeoutFixture::onConnectFailed, this, _2));
+                     bind(&CreateFaceTimeoutFixture::onFaceCreated, this, _1),
+                     bind(&CreateFaceTimeoutFixture::onConnectFailed, this, _2));
 
   BOOST_REQUIRE_EQUAL(limitedIo.run(1, time::seconds(10)), LimitedIo::EXCEED_OPS);
   BOOST_CHECK(face == nullptr);
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index a095a99..435b6d6 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -25,12 +25,12 @@
 
 #include "face/udp-factory.hpp"
 
-#include "factory-test-common.hpp"
 #include "face-system-fixture.hpp"
-#include "tests/limited-io.hpp"
+#include "factory-test-common.hpp"
 #include "test-netif-ip.hpp"
+
 #include <boost/algorithm/string/replace.hpp>
-#include <boost/range/algorithm.hpp>
+#include <boost/range/algorithm/count_if.hpp>
 
 namespace nfd {
 namespace face {
@@ -318,7 +318,7 @@
   parseConfig(CONFIG, false);
   auto udpMcastFaces = this->listUdpMcastFaces();
   BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
-  BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [=] (const Face* face) {
+  BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [this] (const Face* face) {
     return isFaceOnNetif(*face, netifs.front());
   }), 0);
 }
@@ -492,20 +492,13 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
+  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
 
-  std::vector<shared_ptr<const Channel>> expectedChannels;
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
-  expectedChannels.push_back(factory.createChannel("::1", "20071"));
-
-  for (const auto& i : factory.getChannels()) {
-    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
-    BOOST_REQUIRE(pos != expectedChannels.end());
-    expectedChannels.erase(pos);
-  }
-
-  BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
+  std::set<std::string> expected;
+  expected.insert(factory.createChannel("127.0.0.1", "20070")->getUri().toString());
+  expected.insert(factory.createChannel("127.0.0.1", "20071")->getUri().toString());
+  expected.insert(factory.createChannel("::1", "20071")->getUri().toString());
+  checkChannelListEqual(factory, expected);
 }
 
 BOOST_AUTO_TEST_CASE(CreateChannel)
@@ -592,7 +585,7 @@
                         });
 }
 
-BOOST_AUTO_TEST_CASE(FaceCreate)
+BOOST_AUTO_TEST_CASE(CreateFace)
 {
   createFace(factory,
              FaceUri("udp4://127.0.0.1:6363"),
@@ -625,7 +618,7 @@
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
-BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
+BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
 {
   factory.createChannel("127.0.0.1", "20071");
 
diff --git a/tests/daemon/face/unix-stream-factory.t.cpp b/tests/daemon/face/unix-stream-factory.t.cpp
index 5bd0506..76b1cb7 100644
--- a/tests/daemon/face/unix-stream-factory.t.cpp
+++ b/tests/daemon/face/unix-stream-factory.t.cpp
@@ -25,9 +25,8 @@
 
 #include "face/unix-stream-factory.hpp"
 
-#include "factory-test-common.hpp"
 #include "face-system-fixture.hpp"
-#include "tests/limited-io.hpp"
+#include "factory-test-common.hpp"
 
 namespace nfd {
 namespace face {
@@ -97,38 +96,31 @@
 
 BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
 
-BOOST_AUTO_TEST_CASE(ChannelMap)
+BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
-  shared_ptr<UnixStreamChannel> channel1a = factory.createChannel(CHANNEL_PATH1);
-  BOOST_CHECK_EQUAL(channel1, channel1a);
-  std::string channel1uri = channel1->getUri().toString();
-  BOOST_CHECK_EQUAL(channel1uri.find("unix:///"), 0); // third '/' is the path separator
-  BOOST_CHECK_EQUAL(channel1uri.rfind(CHANNEL_PATH1),
-                    channel1uri.size() - std::string(CHANNEL_PATH1).size());
+  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
 
-  shared_ptr<UnixStreamChannel> channel2 = factory.createChannel(CHANNEL_PATH2);
+  std::set<std::string> expected;
+  expected.insert(factory.createChannel(CHANNEL_PATH1)->getUri().toString());
+  expected.insert(factory.createChannel(CHANNEL_PATH2)->getUri().toString());
+  checkChannelListEqual(factory, expected);
+}
+
+BOOST_AUTO_TEST_CASE(CreateChannel)
+{
+  auto channel1 = factory.createChannel(CHANNEL_PATH1);
+  auto channel1a = factory.createChannel(CHANNEL_PATH1);
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  std::string uri = channel1->getUri().toString();
+  BOOST_CHECK_EQUAL(uri.find("unix:///"), 0); // third '/' is the path separator
+  BOOST_CHECK_EQUAL(uri.rfind(CHANNEL_PATH1),
+                    uri.size() - std::string(CHANNEL_PATH1).size());
+
+  auto channel2 = factory.createChannel(CHANNEL_PATH2);
   BOOST_CHECK_NE(channel1, channel2);
 }
 
-BOOST_AUTO_TEST_CASE(GetChannels)
-{
-  BOOST_CHECK(factory.getChannels().empty());
-
-  std::vector<shared_ptr<const Channel>> expectedChannels;
-  expectedChannels.push_back(factory.createChannel(CHANNEL_PATH1));
-  expectedChannels.push_back(factory.createChannel(CHANNEL_PATH2));
-
-  for (const auto& channel : factory.getChannels()) {
-    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), channel);
-    BOOST_REQUIRE(pos != expectedChannels.end());
-    expectedChannels.erase(pos);
-  }
-
-  BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
-}
-
-BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
+BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
 {
   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 c17e620..47b1a0f 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -25,9 +25,8 @@
 
 #include "face/websocket-factory.hpp"
 
-#include "factory-test-common.hpp"
 #include "face-system-fixture.hpp"
-#include "tests/limited-io.hpp"
+#include "factory-test-common.hpp"
 
 namespace nfd {
 namespace face {
@@ -173,23 +172,16 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
+  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
 
-  std::vector<shared_ptr<const Channel>> expectedChannels;
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
-  expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
-  expectedChannels.push_back(factory.createChannel("::1", "20071"));
-
-  for (const auto& i : factory.getChannels()) {
-    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
-    BOOST_REQUIRE(pos != expectedChannels.end());
-    expectedChannels.erase(pos);
-  }
-
-  BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
+  std::set<std::string> expected;
+  expected.insert(factory.createChannel("127.0.0.1", "20070")->getUri().toString());
+  expected.insert(factory.createChannel("127.0.0.1", "20071")->getUri().toString());
+  expected.insert(factory.createChannel("::1", "20071")->getUri().toString());
+  checkChannelListEqual(factory, expected);
 }
 
-BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
+BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
 {
   createFace(factory,
              FaceUri("ws://127.0.0.1:20070"),