tests: use preconditions to skip test cases

Change-Id: I33e239ef033f9b991a425e20326d8dfdb5318095
diff --git a/tests/unit/net/dns.t.cpp b/tests/unit/net/dns.t.cpp
index c1e8679..b28d6ed 100644
--- a/tests/unit/net/dns.t.cpp
+++ b/tests/unit/net/dns.t.cpp
@@ -36,10 +36,8 @@
 {
 public:
   void
-  onSuccess(const boost::asio::ip::address& resolvedAddress,
-            const boost::asio::ip::address& expectedAddress,
-            bool isValid,
-            bool shouldCheckAddress = false)
+  onSuccess(const ip::address& resolvedAddress, const ip::address& expectedAddress,
+            bool isValid, bool shouldCheckAddress = false)
   {
     ++m_nSuccesses;
 
@@ -72,10 +70,9 @@
 BOOST_AUTO_TEST_SUITE(Net)
 BOOST_FIXTURE_TEST_SUITE(TestDns, DnsFixture)
 
-BOOST_AUTO_TEST_CASE(Failure)
+BOOST_AUTO_TEST_CASE(Failure,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv4OrIpv6))
 {
-  SKIP_IF_IP_UNAVAILABLE();
-
   asyncResolve("nothost.nothost.nothost.arpa",
                std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), false, false),
                [this] (auto&&...) { onFailure(true); },
@@ -86,10 +83,9 @@
   BOOST_CHECK_EQUAL(m_nSuccesses, 0);
 }
 
-BOOST_AUTO_TEST_CASE(Ipv4)
+BOOST_AUTO_TEST_CASE(Ipv4,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv4))
 {
-  SKIP_IF_IPV4_UNAVAILABLE();
-
   asyncResolve("192.0.2.1",
                std::bind(&DnsFixture::onSuccess, this, _1, ip::make_address_v4("192.0.2.1"), true, true),
                [this] (auto&&...) { onFailure(false); },
@@ -100,10 +96,9 @@
   BOOST_CHECK_EQUAL(m_nSuccesses, 1);
 }
 
-BOOST_AUTO_TEST_CASE(Ipv6)
+BOOST_AUTO_TEST_CASE(Ipv6,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv6))
 {
-  SKIP_IF_IPV6_UNAVAILABLE();
-
   asyncResolve("ipv6.google.com", // only IPv6 address should be available
                std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
                [this] (auto&&...) { onFailure(false); },
@@ -120,11 +115,10 @@
   BOOST_CHECK_EQUAL(m_nSuccesses, 2);
 }
 
-BOOST_AUTO_TEST_CASE(WithAddressSelector)
+BOOST_AUTO_TEST_CASE(WithAddressSelector,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv4)
+  * ut::precondition(NetworkConfigurationDetector::hasIpv6))
 {
-  SKIP_IF_IPV4_UNAVAILABLE();
-  SKIP_IF_IPV6_UNAVAILABLE();
-
   asyncResolve("named-data.net",
                std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), true, false),
                [this] (auto&&...) { onFailure(false); },
diff --git a/tests/unit/net/face-uri.t.cpp b/tests/unit/net/face-uri.t.cpp
index f306a94..e1b7ee9 100644
--- a/tests/unit/net/face-uri.t.cpp
+++ b/tests/unit/net/face-uri.t.cpp
@@ -208,10 +208,9 @@
 }
 
 BOOST_FIXTURE_TEST_CASE(CanonizeUdpV4, CanonizeFixture,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv4)
   * ut::expected_failures(1))
 {
-  SKIP_IF_IPV4_UNAVAILABLE();
-
   // IPv4 unicast
   runTest("udp4://192.0.2.1:6363", true, "udp4://192.0.2.1:6363");
   runTest("udp://192.0.2.2:6363", true, "udp4://192.0.2.2:6363");
@@ -236,10 +235,9 @@
 }
 
 BOOST_FIXTURE_TEST_CASE(CanonizeUdpV6, CanonizeFixture,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv6)
   * ut::expected_failures(1))
 {
-  SKIP_IF_IPV6_UNAVAILABLE();
-
   // IPv6 unicast
   runTest("udp6://[2001:db8::1]:6363", true, "udp6://[2001:db8::1]:6363");
   runTest("udp6://[2001:db8::1]", true, "udp6://[2001:db8::1]:6363");
@@ -338,10 +336,9 @@
 }
 
 BOOST_FIXTURE_TEST_CASE(CanonizeTcpV4, CanonizeFixture,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv4)
   * ut::expected_failures(1))
 {
-  SKIP_IF_IPV4_UNAVAILABLE();
-
   // IPv4 unicast
   runTest("tcp4://192.0.2.1:6363", true, "tcp4://192.0.2.1:6363");
   runTest("tcp://192.0.2.2:6363", true, "tcp4://192.0.2.2:6363");
@@ -377,10 +374,9 @@
 }
 
 BOOST_FIXTURE_TEST_CASE(CanonizeTcpV6, CanonizeFixture,
+  * ut::precondition(NetworkConfigurationDetector::hasIpv6)
   * ut::expected_failures(1))
 {
-  SKIP_IF_IPV6_UNAVAILABLE();
-
   // IPv6 unicast
   runTest("tcp6://[2001:db8::1]:6363", true, "tcp6://[2001:db8::1]:6363");
   runTest("tcp6://[2001:db8::1]", true, "tcp6://[2001:db8::1]:6363");
diff --git a/tests/unit/net/network-configuration-detector.cpp b/tests/unit/net/network-configuration-detector.cpp
index 44cae39..e9b39df 100644
--- a/tests/unit/net/network-configuration-detector.cpp
+++ b/tests/unit/net/network-configuration-detector.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -27,36 +27,23 @@
 
 namespace ndn::tests {
 
-bool
-NetworkConfigurationDetector::hasIpv4()
-{
-  if (!s_isInitialized) {
-    detect();
-  }
-  return s_hasIpv4;
-}
-
-bool
-NetworkConfigurationDetector::hasIpv6()
-{
-  if (!s_isInitialized) {
-    detect();
-  }
-  return s_hasIpv6;
-}
-
 void
 NetworkConfigurationDetector::detect()
 {
+  static bool isInitialized = false;
+  if (isInitialized) {
+    return;
+  }
+
   boost::asio::io_context io;
   boost::asio::ip::udp::resolver resolver(io);
 
   boost::system::error_code ec;
-  // The specified hostname must have both A and AAAA records
+  // Use a hostname known to have both A and AAAA records
   auto results = resolver.resolve("a.root-servers.net", "", ec);
-
   if (!ec) {
     for (const auto& i : results) {
+      s_hasIp = true;
       if (i.endpoint().address().is_v4()) {
         s_hasIpv4 = true;
       }
@@ -65,7 +52,17 @@
       }
     }
   }
-  s_isInitialized = true;
+
+  if (!s_hasIp) {
+    s_hasIp.message() << "IP connectivity is unavailable";
+  }
+  if (!s_hasIpv4) {
+    s_hasIpv4.message() << "IPv4 connectivity is unavailable";
+  }
+  if (!s_hasIpv6) {
+    s_hasIpv6.message() << "IPv6 connectivity is unavailable";
+  }
+  isInitialized = true;
 }
 
 } // namespace ndn::tests
diff --git a/tests/unit/net/network-configuration-detector.hpp b/tests/unit/net/network-configuration-detector.hpp
index 7264e68..58abba0 100644
--- a/tests/unit/net/network-configuration-detector.hpp
+++ b/tests/unit/net/network-configuration-detector.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,50 +22,42 @@
 #ifndef NDN_CXX_TESTS_UNIT_NET_NETWORK_CONFIGURATION_DETECTOR_HPP
 #define NDN_CXX_TESTS_UNIT_NET_NETWORK_CONFIGURATION_DETECTOR_HPP
 
-#define SKIP_IF_IPV4_UNAVAILABLE() \
-  do { \
-    if (!::ndn::tests::NetworkConfigurationDetector::hasIpv4()) { \
-      BOOST_WARN_MESSAGE(false, "skipping assertions that require IPv4 support"); \
-      return; \
-    } \
-  } while (false)
-
-#define SKIP_IF_IPV6_UNAVAILABLE() \
-  do { \
-    if (!::ndn::tests::NetworkConfigurationDetector::hasIpv6()) { \
-      BOOST_WARN_MESSAGE(false, "skipping assertions that require IPv6 support"); \
-      return; \
-    } \
-  } while (false)
-
-#define SKIP_IF_IP_UNAVAILABLE() \
-  do { \
-    if (!::ndn::tests::NetworkConfigurationDetector::hasIpv4() && \
-        !::ndn::tests::NetworkConfigurationDetector::hasIpv6()) { \
-      BOOST_WARN_MESSAGE(false, "skipping assertions that require either IPv4 or IPv6 support"); \
-      return; \
-    } \
-  } while (false)
+#include "tests/boost-test.hpp"
 
 namespace ndn::tests {
 
 class NetworkConfigurationDetector
 {
 public:
-  static bool
-  hasIpv4();
+  static boost::test_tools::assertion_result
+  hasIpv4(ut::test_unit_id = {})
+  {
+    detect();
+    return s_hasIpv4;
+  }
 
-  static bool
-  hasIpv6();
+  static boost::test_tools::assertion_result
+  hasIpv6(ut::test_unit_id = {})
+  {
+    detect();
+    return s_hasIpv6;
+  }
+
+  static boost::test_tools::assertion_result
+  hasIpv4OrIpv6(ut::test_unit_id = {})
+  {
+    detect();
+    return s_hasIp;
+  }
 
 private:
   static void
   detect();
 
 private:
-  static inline bool s_isInitialized = false;
-  static inline bool s_hasIpv4 = false;
-  static inline bool s_hasIpv6 = false;
+  static inline boost::test_tools::assertion_result s_hasIp = false;
+  static inline boost::test_tools::assertion_result s_hasIpv4 = false;
+  static inline boost::test_tools::assertion_result s_hasIpv6 = false;
 };
 
 } // namespace ndn::tests