tests: MulticastUdpTransport test suite improvements

refs #3346

Change-Id: I31b272b9b99d97ed317cf534d9e1bc4592bde77d
diff --git a/tests/daemon/face/multicast-udp-transport.t.cpp b/tests/daemon/face/multicast-udp-transport.t.cpp
index 545d4b8..ac1e33c 100644
--- a/tests/daemon/face/multicast-udp-transport.t.cpp
+++ b/tests/daemon/face/multicast-udp-transport.t.cpp
@@ -23,43 +23,82 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "face/multicast-udp-transport.hpp"
 #include "transport-test-common.hpp"
 
+#include "multicast-udp-transport-fixture.hpp"
+
 namespace nfd {
 namespace face {
 namespace tests {
 
-using namespace nfd::tests;
-namespace ip = boost::asio::ip;
-using ip::udp;
-
 BOOST_AUTO_TEST_SUITE(Face)
-BOOST_FIXTURE_TEST_SUITE(TestMulticastUdpTransport, BaseFixture)
+BOOST_FIXTURE_TEST_SUITE(TestMulticastUdpTransport, MulticastUdpTransportFixture)
 
-BOOST_AUTO_TEST_CASE(StaticPropertiesIpv4)
+BOOST_AUTO_TEST_CASE(StaticPropertiesNonLocalIpv4)
 {
-  udp::socket sockRx(g_io);
-  sockRx.open(udp::v4());
-  sockRx.set_option(udp::socket::reuse_address(true));
-  sockRx.bind(udp::endpoint(ip::address::from_string("127.0.0.1"), 7001));
+  SKIP_IF_IP_UNAVAILABLE(defaultAddr);
+  initialize(defaultAddr);
 
-  udp::socket sockTx(g_io);
-  sockTx.open(udp::v4());
-  sockTx.set_option(udp::socket::reuse_address(true));
-  sockTx.bind(udp::endpoint(udp::v4(), 7001));
+  checkStaticPropertiesInitialized(*transport);
 
-  MulticastUdpTransport transport(sockRx.local_endpoint(),
-                                  udp::endpoint(ip::address::from_string("230.15.19.47"), 7001),
-                                  std::move(sockRx), std::move(sockTx));
-  checkStaticPropertiesInitialized(transport);
+  BOOST_CHECK_EQUAL(transport->getLocalUri(),
+                    FaceUri("udp4://" + defaultAddr.to_string() + ":" + to_string(localEp.port())));
+  BOOST_CHECK_EQUAL(transport->getRemoteUri(),
+                    FaceUri("udp4://" + multicastEp.address().to_string() + ":" + to_string(multicastEp.port())));
+  BOOST_CHECK_EQUAL(transport->getScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+  BOOST_CHECK_EQUAL(transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  BOOST_CHECK_EQUAL(transport->getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
+  BOOST_CHECK_EQUAL(transport->getMtu(), 65535 - 60 - 8);
+}
 
-  BOOST_CHECK_EQUAL(transport.getLocalUri(), FaceUri("udp4://127.0.0.1:7001"));
-  BOOST_CHECK_EQUAL(transport.getRemoteUri(), FaceUri("udp4://230.15.19.47:7001"));
-  BOOST_CHECK_EQUAL(transport.getScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
-  BOOST_CHECK_EQUAL(transport.getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
-  BOOST_CHECK_EQUAL(transport.getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
-  BOOST_CHECK_EQUAL(transport.getMtu(), 65535 - 60 - 8);
+BOOST_AUTO_TEST_CASE(ReceiveMultipleRemoteEndpoints)
+{
+  SKIP_IF_IP_UNAVAILABLE(defaultAddr);
+  initialize(defaultAddr);
+
+  // remoteSockRx2 unnecessary for this test case - only remoteSockTx2 is needed
+  udp::socket remoteSockTx2(g_io);
+  remoteSockTx2.open(udp::v4());
+  remoteSockTx2.set_option(udp::socket::reuse_address(true));
+  remoteSockTx2.set_option(ip::multicast::enable_loopback(true));
+  remoteSockTx2.bind(udp::endpoint(ip::address_v4::any(), 7071));
+
+  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
+  ndn::Buffer buf1(pkt1.begin(), pkt1.end());
+  remoteWrite(buf1);
+
+  Block pkt2 = ndn::encoding::makeStringBlock(301, "world");
+  ndn::Buffer buf2(pkt2.begin(), pkt2.end());
+  remoteWrite(buf2);
+
+  BOOST_CHECK_EQUAL(transport->getCounters().nInPackets, 2);
+  BOOST_CHECK_EQUAL(transport->getCounters().nInBytes, buf1.size() + buf2.size());
+  BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
+
+  BOOST_REQUIRE_EQUAL(receivedPackets->size(), 2);
+  BOOST_CHECK_EQUAL(receivedPackets->at(0).remoteEndpoint,
+                    receivedPackets->at(1).remoteEndpoint);
+
+  udp::endpoint destEp(multicastEp.address(), localEp.port());
+  remoteSockTx2.async_send_to(boost::asio::buffer(buf1), destEp,
+    [] (const boost::system::error_code& error, size_t) {
+      BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
+    });
+  remoteSockTx2.async_send_to(boost::asio::buffer(buf2), destEp,
+    [] (const boost::system::error_code& error, size_t) {
+      BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
+    });
+  limitedIo.defer(time::seconds(1));
+
+  BOOST_CHECK_EQUAL(transport->getCounters().nInPackets, 4);
+  BOOST_CHECK_EQUAL(transport->getCounters().nInBytes, 2 * buf1.size() + 2 * buf2.size());
+  BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
+
+  BOOST_REQUIRE_EQUAL(receivedPackets->size(), 4);
+  BOOST_CHECK_EQUAL(receivedPackets->at(2).remoteEndpoint,
+                    receivedPackets->at(3).remoteEndpoint);
+  BOOST_CHECK_NE(receivedPackets->at(0).remoteEndpoint,
+                 receivedPackets->at(2).remoteEndpoint);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestMulticastUdpTransport