ci: stop adding capabilities before running unit tests

This ensures that all tests pass (or are automatically skipped)
when run as an unprivileged user.

Change-Id: If8b66fd6555de455648576565b1c6cbd02695d1b
Refs: #3418
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
index 417d1a6..06b2ad5 100755
--- a/.jenkins.d/00-deps.sh
+++ b/.jenkins.d/00-deps.sh
@@ -13,7 +13,6 @@
     brew update
     brew upgrade
     brew install boost pkg-config cryptopp openssl $EXTRA_FLAGS
-    brew link --force openssl
     brew cleanup
 fi
 
@@ -21,6 +20,6 @@
     set -x
     sudo apt-get -qq update
     sudo apt-get -qq install build-essential pkg-config libboost-all-dev \
-                             libcrypto++-dev libsqlite3-dev libpcap-dev \
-                             libssl-dev
+                             libcrypto++-dev libsqlite3-dev libssl-dev \
+                             libpcap-dev
 fi
diff --git a/.jenkins.d/20-tests.sh b/.jenkins.d/20-tests.sh
index 89ff5da..17419ce 100755
--- a/.jenkins.d/20-tests.sh
+++ b/.jenkins.d/20-tests.sh
@@ -9,38 +9,42 @@
 rm -Rf ~/.ndnx ~/.ndn
 
 if has OSX $NODE_LABELS; then
-  security unlock-keychain -p "named-data"
-  sudo chgrp admin /dev/bpf*
-  sudo chmod g+rw /dev/bpf*
-fi
-
-if has Linux $NODE_LABELS; then
-  sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-core || true
-  sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-daemon || true
-  sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-rib || true
-  # unit-tests-tools does not need capabilities
+    security unlock-keychain -p named-data
 fi
 
 ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
 
-# Run unit tests
-# Core
-if [[ -n $XUNIT ]]; then
-  ./build/unit-tests-core -l all -- --log_format2=XML --log_sink2=build/xunit-core-report.xml
-  sudo ./build/unit-tests-core -t TestPrivilegeHelper -l all -- --log_format2=XML --log_sink2=build/xunit-core-sudo-report.xml
+count=0
 
-  ./build/unit-tests-daemon -l all -- --log_format2=XML --log_sink2=build/xunit-daemon-report.xml
+# Helper function
+run_tests() {
+    local sudo=
+    if [[ $1 == sudo ]]; then
+        sudo=$1
+        shift
+    fi
 
-  ./build/unit-tests-rib -l all -- --log_format2=XML --log_sink2=build/xunit-rib-report.xml
+    local module=$1
+    shift
 
-  ./build/unit-tests-tools -l all -- --log_format2=XML --log_sink2=build/xunit-tools-report.xml
-else
-  ./build/unit-tests-core -l test_suite
-  sudo ./build/unit-tests-core -t TestPrivilegeHelper -l test_suite
+    if [[ -n $XUNIT ]]; then
+        ${sudo} ./build/unit-tests-${module} -l all "$@" -- --log_format2=XML --log_sink2="build/xunit-${count}-${module}${sudo:+-}${sudo}.xml"
+        ((count+=1))
+    else
+        ${sudo} ./build/unit-tests-${module} -l test_suite "$@"
+    fi
+}
 
-  ./build/unit-tests-daemon -l test_suite
+# First run all tests as unprivileged user
+run_tests core
+run_tests daemon
+run_tests rib
+run_tests tools
 
-  ./build/unit-tests-rib -l test_suite
+# Then use sudo to run those tests that need superuser powers
+run_tests sudo core -t TestPrivilegeHelper
+run_tests sudo daemon -t Face/TestEthernetFactory,TestEthernetTransport
+run_tests sudo daemon -t Mgmt/TestGeneralConfigSection/UserAndGroupConfig,NoUserConfig
+run_tests sudo daemon -t Mgmt/TestFaceManager/ProcessConfig/ProcessSectionUdp,ProcessSectionUdpMulticastReinit,ProcessSectionEther,ProcessSectionEtherMulticastReinit
 
-  ./build/unit-tests-tools -l test_suite
-fi
+unset count
diff --git a/.jenkins.d/30-coverage.sh b/.jenkins.d/30-coverage.sh
index a00f8f1..f211681 100755
--- a/.jenkins.d/30-coverage.sh
+++ b/.jenkins.d/30-coverage.sh
@@ -5,7 +5,10 @@
 JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
 source "$JDIR"/util.sh
 
-if [[ "$JOB_NAME" == *"code-coverage" ]]; then
-  BASE="`pwd | sed -e 's|/|\\\/|g'`\\"
-  (cd build && gcovr -x -f $BASE/core -f $BASE/daemon -f $BASE/rib -r ../ -o coverage.xml ./)
+if [[ $JOB_NAME == *"code-coverage" ]]; then
+    gcovr --output=coverage.xml \
+          --filter="$PWD/core" --filter="$PWD/daemon" --filter="$PWD/rib" --filter="$PWD/tools" \
+          --root=. \
+          --xml \
+          build
 fi
diff --git a/tests/core/privilege-helper.t.cpp b/tests/core/privilege-helper.t.cpp
index 84c5f39..ce024e9 100644
--- a/tests/core/privilege-helper.t.cpp
+++ b/tests/core/privilege-helper.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -35,10 +35,7 @@
 BOOST_AUTO_TEST_CASE(DropRaise)
 {
 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
-  if (::geteuid() != 0) {
-    BOOST_TEST_MESSAGE("This test case needs to be run as super user, skipping");
-    return;
-  }
+  SKIP_IF_NOT_SUPERUSER();
 
   // The following assumes that nobody/nogroup is present on the test system
   BOOST_CHECK_NO_THROW(PrivilegeHelper::initialize("nobody", "nogroup"));
@@ -50,14 +47,14 @@
   // separate runElevated case to improve log reporting (otherwise output is unreadable)
   BOOST_CHECK_NO_THROW(PrivilegeHelper::runElevated([]{}));
   PrivilegeHelper::runElevated([] {
-      BOOST_CHECK_EQUAL(::geteuid(), 0);
-    });
+    BOOST_CHECK_EQUAL(::geteuid(), 0);
+  });
   BOOST_CHECK_NE(::geteuid(), 0);
 
   BOOST_CHECK_NO_THROW(PrivilegeHelper::raise());
   BOOST_CHECK_EQUAL(::geteuid(), 0);
 #else
-  BOOST_TEST_MESSAGE("Skipping test, since drop/raise privileges is not supported on this platform");
+  BOOST_TEST_MESSAGE("Dropping/raising privileges not supported on this platform, skipping");
 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
 }
 
diff --git a/tests/daemon/mgmt/face-manager-process-config.t.cpp b/tests/daemon/mgmt/face-manager-process-config.t.cpp
index 16996b8..0ccc75c 100644
--- a/tests/daemon/mgmt/face-manager-process-config.t.cpp
+++ b/tests/daemon/mgmt/face-manager-process-config.t.cpp
@@ -58,7 +58,6 @@
   ConfigFile m_config;
 };
 
-
 BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceManagerProcessConfigFixture)
 
 #ifdef HAVE_UNIX_SOCKETS
@@ -120,7 +119,6 @@
     "    listen hello\n"
     "  }\n"
     "}\n";
-
   BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
   BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
 }
@@ -312,9 +310,8 @@
   auto factory = dynamic_pointer_cast<UdpFactory>(m_manager.m_factories.find("udp")->second);
   BOOST_REQUIRE(factory != nullptr);
 
-  if (factory->getMulticastFaces().size() == 0) {
-    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
-                       "no UDP multicast faces are available");
+  if (factory->getMulticastFaces().empty()) {
+    BOOST_WARN_MESSAGE(false, "skipping assertions that require at least one UDP multicast face");
     return;
   }
 
@@ -335,6 +332,7 @@
 
 BOOST_AUTO_TEST_CASE(ProcessSectionEther)
 {
+  SKIP_IF_NOT_SUPERUSER();
 
   const std::string CONFIG =
     "face_system\n"
@@ -345,7 +343,6 @@
     "    mcast_group 01:00:5E:00:17:AA\n"
     "  }\n"
     "}\n";
-
   BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
   BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
 }
@@ -395,6 +392,8 @@
 
 BOOST_AUTO_TEST_CASE(ProcessSectionEtherMulticastReinit)
 {
+  SKIP_IF_NOT_SUPERUSER();
+
   const std::string CONFIG_WITH_MCAST =
     "face_system\n"
     "{\n"
@@ -409,9 +408,8 @@
   auto factory = dynamic_pointer_cast<EthernetFactory>(m_manager.m_factories.find("ether")->second);
   BOOST_REQUIRE(factory != nullptr);
 
-  if (factory->getMulticastFaces().size() == 0) {
-    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
-                       "no Ethernet multicast faces are available");
+  if (factory->getMulticastFaces().empty()) {
+    BOOST_WARN_MESSAGE(false, "skipping assertions that require at least one Ethernet multicast face");
     return;
   }
 
diff --git a/tests/daemon/mgmt/general-config-section.t.cpp b/tests/daemon/mgmt/general-config-section.t.cpp
index d3af366..26e87ea 100644
--- a/tests/daemon/mgmt/general-config-section.t.cpp
+++ b/tests/daemon/mgmt/general-config-section.t.cpp
@@ -28,6 +28,8 @@
 
 #include "tests/test-common.hpp"
 
+#include <cstring>
+
 namespace nfd {
 namespace general {
 namespace tests {
@@ -37,17 +39,18 @@
 class GeneralConfigSectionFixture : public BaseFixture
 {
 public:
+#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
   ~GeneralConfigSectionFixture()
   {
-#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
     // revert changes to s_normalUid/s_normalGid, if any
     PrivilegeHelper::s_normalUid = ::geteuid();
     PrivilegeHelper::s_normalGid = ::getegid();
-#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
   }
+#endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
 };
 
-BOOST_FIXTURE_TEST_SUITE(MgmtGeneralConfigSection, GeneralConfigSectionFixture)
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_FIXTURE_TEST_SUITE(TestGeneralConfigSection, GeneralConfigSectionFixture)
 
 BOOST_AUTO_TEST_CASE(DefaultConfig)
 {
@@ -113,12 +116,6 @@
 
 #endif // HAVE_PRIVILEGE_DROP_AND_ELEVATE
 
-static bool
-checkExceptionMessage(const ConfigFile::Error& error, const std::string& expected)
-{
-  return error.what() == expected;
-}
-
 BOOST_AUTO_TEST_CASE(InvalidUserConfig)
 {
   const std::string CONFIG =
@@ -130,10 +127,12 @@
   ConfigFile configFile;
   general::setConfigFile(configFile);
 
-  const std::string expected = "Invalid value for \"user\" in \"general\" section";
-  BOOST_REQUIRE_EXCEPTION(configFile.parse(CONFIG, true, "test-general-config-section"),
-                          ConfigFile::Error,
-                          bind(&checkExceptionMessage, _1, expected));
+  BOOST_CHECK_EXCEPTION(configFile.parse(CONFIG, true, "test-general-config-section"),
+                        ConfigFile::Error,
+                        [] (const ConfigFile::Error& e) {
+                          return std::strcmp(e.what(),
+                                             "Invalid value for \"user\" in \"general\" section") == 0;
+                        });
 }
 
 BOOST_AUTO_TEST_CASE(InvalidGroupConfig)
@@ -147,13 +146,16 @@
   ConfigFile configFile;
   general::setConfigFile(configFile);
 
-  const std::string expected = "Invalid value for \"group\" in \"general\" section";
-  BOOST_REQUIRE_EXCEPTION(configFile.parse(CONFIG, true, "test-general-config-section"),
-                          ConfigFile::Error,
-                          bind(&checkExceptionMessage, _1, expected));
+  BOOST_CHECK_EXCEPTION(configFile.parse(CONFIG, true, "test-general-config-section"),
+                        ConfigFile::Error,
+                        [] (const ConfigFile::Error& e) {
+                          return std::strcmp(e.what(),
+                                             "Invalid value for \"group\" in \"general\" section") == 0;
+                        });
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestGeneralConfigSection
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
 
 } // namespace tests
 } // namespace general
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index ffff22a..9ea3d3c 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -38,7 +38,7 @@
 #define SKIP_IF_NOT_SUPERUSER() \
   do { \
     if (::geteuid() != 0) { \
-      BOOST_TEST_MESSAGE("This test case needs to be run as superuser, skipping"); \
+      BOOST_WARN_MESSAGE(false, "skipping assertions that require superuser privileges"); \
       return; \
     } \
   } while (false)