face: set EthernetTransport UP/DOWN based on netif state

refs #3352

Change-Id: I24476ee293d229cd9222996f91f31cfb15728c47
diff --git a/tests/daemon/face/multicast-ethernet-transport.t.cpp b/tests/daemon/face/multicast-ethernet-transport.t.cpp
index 511f57a..d4e1fce 100644
--- a/tests/daemon/face/multicast-ethernet-transport.t.cpp
+++ b/tests/daemon/face/multicast-ethernet-transport.t.cpp
@@ -59,6 +59,34 @@
   BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERMANENT), true);
 }
 
+BOOST_AUTO_TEST_CASE(NetifStateChange)
+{
+  SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
+  initializeMulticast();
+  BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
+
+  // simulate 'ip link set IFNAME down'
+  scheduler::schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::DOWN); });
+  transport->afterStateChange.connectSingleShot([&] (TransportState oldState, TransportState newState) {
+    BOOST_CHECK_EQUAL(oldState, TransportState::UP);
+    BOOST_CHECK_EQUAL(newState, TransportState::DOWN);
+    limitedIo.afterOp();
+  });
+  BOOST_CHECK_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
+  BOOST_CHECK_EQUAL(transport->getState(), TransportState::DOWN);
+
+  // simulate 'ip link set IFNAME up'
+  scheduler::schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::NO_CARRIER); });
+  scheduler::schedule(80_ms, [=] { netif->setState(ndn::net::InterfaceState::RUNNING); });
+  transport->afterStateChange.connectSingleShot([&] (TransportState oldState, TransportState newState) {
+    BOOST_CHECK_EQUAL(oldState, TransportState::DOWN);
+    BOOST_CHECK_EQUAL(newState, TransportState::UP);
+    limitedIo.afterOp();
+  });
+  BOOST_CHECK_EQUAL(limitedIo.run(1, 1_s), LimitedIo::EXCEED_OPS);
+  BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
+}
+
 BOOST_AUTO_TEST_CASE(Close)
 {
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);