tests: refactor common test infrastructure and fixtures

Change-Id: I597c11130eefa2cc2846ee6655c85dc04f2f22ef
diff --git a/tests/unit/net/collect-netifs.cpp b/tests/unit/net/collect-netifs.cpp
deleted file mode 100644
index fe866af..0000000
--- a/tests/unit/net/collect-netifs.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2018 Regents of the University of California,
- *                         Arizona Board of Regents,
- *                         Colorado State University,
- *                         University Pierre & Marie Curie, Sorbonne University,
- *                         Washington University in St. Louis,
- *                         Beijing Institute of Technology,
- *                         The University of Memphis.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "tests/unit/net/collect-netifs.hpp"
-#include "ndn-cxx/net/network-monitor.hpp"
-
-#include <boost/asio/io_service.hpp>
-
-namespace ndn {
-namespace net {
-namespace tests {
-
-std::vector<shared_ptr<const NetworkInterface>>
-collectNetworkInterfaces(bool allowCached)
-{
-  static optional<std::vector<shared_ptr<const NetworkInterface>>> cached;
-
-  if (!allowCached || !cached) {
-    boost::asio::io_service io;
-    NetworkMonitor netmon(io);
-
-    if (netmon.getCapabilities() & NetworkMonitor::CAP_ENUM) {
-      netmon.onEnumerationCompleted.connect([&io] { io.stop(); });
-      io.run();
-      io.reset();
-    }
-    cached = netmon.listNetworkInterfaces();
-  }
-
-  return *cached;
-}
-
-} // namespace tests
-} // namespace net
-} // namespace ndn
diff --git a/tests/unit/net/collect-netifs.hpp b/tests/unit/net/collect-netifs.hpp
deleted file mode 100644
index cc104f6..0000000
--- a/tests/unit/net/collect-netifs.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2018 Regents of the University of California,
- *                         Arizona Board of Regents,
- *                         Colorado State University,
- *                         University Pierre & Marie Curie, Sorbonne University,
- *                         Washington University in St. Louis,
- *                         Beijing Institute of Technology,
- *                         The University of Memphis.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#ifndef NDN_TESTS_UNIT_NET_COLLECT_NETIFS_HPP
-#define NDN_TESTS_UNIT_NET_COLLECT_NETIFS_HPP
-
-#include "ndn-cxx/net/network-interface.hpp"
-
-#include <vector>
-
-namespace ndn {
-namespace net {
-namespace tests {
-
-/** \brief Collect information about network interfaces
- *  \param allowCached if true, previously collected information can be returned
- *  \note This function is blocking if \p allowCached is false or no previous information exists
- */
-std::vector<shared_ptr<const NetworkInterface>>
-collectNetworkInterfaces(bool allowCached = true);
-
-} // namespace tests
-} // namespace net
-} // namespace ndn
-
-#endif // NDN_TESTS_UNIT_NET_COLLECT_NETIFS_HPP
diff --git a/tests/unit/net/face-uri.t.cpp b/tests/unit/net/face-uri.t.cpp
index 2b99470..c8f7d16 100644
--- a/tests/unit/net/face-uri.t.cpp
+++ b/tests/unit/net/face-uri.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California,
+ * Copyright (c) 2013-2020 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -26,9 +26,10 @@
  */
 
 #include "ndn-cxx/net/face-uri.hpp"
+#include "ndn-cxx/net/network-interface.hpp"
+#include "ndn-cxx/net/network-monitor.hpp"
 
 #include "tests/boost-test.hpp"
-#include "tests/unit/net/collect-netifs.hpp"
 #include "tests/unit/net/network-configuration-detector.hpp"
 
 namespace ndn {
@@ -37,9 +38,30 @@
 BOOST_AUTO_TEST_SUITE(Net)
 BOOST_AUTO_TEST_SUITE(TestFaceUri)
 
-class CanonizeFixture : noncopyable
+class CanonizeFixture
 {
 protected:
+  CanonizeFixture()
+  {
+    static const auto netifs = [this] {
+      net::NetworkMonitor netmon(m_io);
+      if (netmon.getCapabilities() & net::NetworkMonitor::CAP_ENUM) {
+        netmon.onEnumerationCompleted.connect([this] { m_io.stop(); });
+        m_io.run();
+#if BOOST_VERSION >= 106600
+        m_io.restart();
+#else
+        m_io.reset();
+#endif
+      }
+      return netmon.listNetworkInterfaces();
+    }();
+
+    if (!netifs.empty()) {
+      m_netif = netifs.front();
+    }
+  }
+
   void
   addTest(const std::string& request, bool shouldSucceed, const std::string& expectedUri)
   {
@@ -101,6 +123,9 @@
     BOOST_CHECK_MESSAGE(!tc->m_shouldSucceed, tc->m_message);
   }
 
+protected:
+  shared_ptr<const net::NetworkInterface> m_netif;
+
 private:
   boost::asio::io_service m_io;
   ssize_t m_nPending = 0;
@@ -205,11 +230,9 @@
   BOOST_CHECK_EQUAL(FaceUri("udp4://[2001:db8::1]:6363").isCanonical(), false);
   BOOST_CHECK_EQUAL(FaceUri("udp6://192.0.2.1:6363").isCanonical(), false);
 
-  const auto& networkInterfaces = ndn::net::tests::collectNetworkInterfaces();
-  if (!networkInterfaces.empty()) {
-    const auto& netif = networkInterfaces.front();
-    auto name = netif->getName();
-    auto index = to_string(netif->getIndex());
+  if (m_netif) {
+    auto name = m_netif->getName();
+    auto index = to_string(m_netif->getIndex());
 
     BOOST_CHECK_EQUAL(FaceUri("udp6://[fe80::1%" + name + "]:6363").isCanonical(), true);
     BOOST_CHECK_EQUAL(FaceUri("udp6://[fe80::1%" + index + "]:6363").isCanonical(), false);
@@ -270,11 +293,9 @@
   // IPv4 used with udp6 protocol - not canonical
   addTest("udp6://192.0.2.1:6363", false, "");
 
-  const auto& networkInterfaces = ndn::net::tests::collectNetworkInterfaces();
-  if (!networkInterfaces.empty()) {
-    const auto& netif = networkInterfaces.front();
-    auto name = netif->getName();
-    auto index = to_string(netif->getIndex());
+  if (m_netif) {
+    auto name = m_netif->getName();
+    auto index = to_string(m_netif->getIndex());
 
     addTest("udp6://[fe80::1068:dddb:fe26:fe3f%25" + name + "]:6363", true,
             "udp6://[fe80::1068:dddb:fe26:fe3f%" + name + "]:6363");
@@ -342,11 +363,9 @@
   BOOST_CHECK_EQUAL(FaceUri("tcp4://[2001:db8::1]:6363").isCanonical(), false);
   BOOST_CHECK_EQUAL(FaceUri("tcp6://192.0.2.1:6363").isCanonical(), false);
 
-  const auto& networkInterfaces = ndn::net::tests::collectNetworkInterfaces();
-  if (!networkInterfaces.empty()) {
-    const auto& netif = networkInterfaces.front();
-    auto name = netif->getName();
-    auto index = to_string(netif->getIndex());
+  if (m_netif) {
+    auto name = m_netif->getName();
+    auto index = to_string(m_netif->getIndex());
 
     BOOST_CHECK_EQUAL(FaceUri("tcp6://[fe80::1%" + name + "]:6363").isCanonical(), true);
     BOOST_CHECK_EQUAL(FaceUri("tcp6://[fe80::1%" + index + "]:6363").isCanonical(), false);
@@ -380,11 +399,9 @@
   // IPv6 used with tcp4 protocol - not canonical
   addTest("tcp4://[2001:db8::1]:6363", false, "");
 
-  const auto& networkInterfaces = ndn::net::tests::collectNetworkInterfaces();
-  if (!networkInterfaces.empty()) {
-    const auto& netif = networkInterfaces.front();
-    auto name = netif->getName();
-    auto index = to_string(netif->getIndex());
+  if (m_netif) {
+    auto name = m_netif->getName();
+    auto index = to_string(m_netif->getIndex());
 
     addTest("tcp6://[fe80::1068:dddb:fe26:fe3f%25" + name + "]:6363", true,
             "tcp6://[fe80::1068:dddb:fe26:fe3f%" + name + "]:6363");