tests: revamp Face integrated tests

* Categorize tests into consumer, producer, IO routines.
* Split expressInterest tests.
* Add route toward null face when Interest timeout is expected.
* Merge similar setInterestFilter tests.
* Add test for oversized Data.
* Move InterestFilter-convert-to-Name test into unit tests.

refs #4031

Change-Id: I3356ae7fc9eec942ec7f2fb8b2277fa039464750
diff --git a/tests/integrated/face.cpp b/tests/integrated/face.cpp
index cf7c872..a8492f1 100644
--- a/tests/integrated/face.cpp
+++ b/tests/integrated/face.cpp
@@ -24,567 +24,349 @@
 #define BOOST_TEST_MODULE ndn-cxx Integrated Tests (Face)
 
 #include "face.hpp"
+#include "transport/tcp-transport.hpp"
+#include "transport/unix-transport.hpp"
 #include "util/scheduler.hpp"
 
-#include "identity-management-fixture.hpp"
 #include "boost-test.hpp"
+#include "identity-management-fixture.hpp"
+#include "make-interest-data.hpp"
 
 #include <stdio.h>
 #include <thread>
 #include <mutex>
 #include <condition_variable>
+#include <boost/mpl/vector.hpp>
 
 namespace ndn {
 namespace tests {
 
-struct PibDirWithDefaultTpm
+static Name
+makeVeryLongName(Name prefix = Name())
 {
-  const std::string PATH = "build/keys-with-default-tpm";
-};
-
-class FacesFixture : public IdentityManagementFixture
-{
-public:
-  FacesFixture()
-    : nData(0)
-    , nNacks(0)
-    , nTimeouts(0)
-    , regPrefixId(0)
-    , nInInterests(0)
-    , nInInterests2(0)
-    , nRegFailures(0)
-  {
-  }
-
-  void
-  onData()
-  {
-    ++nData;
-  }
-
-  void
-  onNack()
-  {
-    ++nNacks;
-  }
-
-  void
-  onTimeout()
-  {
-    ++nTimeouts;
-  }
-
-  void
-  onInterest(Face& face,
-             const Name&, const Interest&)
-  {
-    ++nInInterests;
-
-    face.unsetInterestFilter(regPrefixId);
-  }
-
-  void
-  onInterest2(Face& face,
-              const Name&, const Interest&)
-  {
-    ++nInInterests2;
-
-    face.unsetInterestFilter(regPrefixId2);
-  }
-
-  void
-  onInterestRegex(Face& face,
-                  const InterestFilter&, const Interest&)
-  {
-    ++nInInterests;
-  }
-
-  void
-  onInterestRegexError(Face& face,
-                       const Name&, const Interest&)
-  {
-    BOOST_FAIL("InterestFilter::Error should have been triggered");
-  }
-
-  void
-  onRegFailed()
-  {
-    ++nRegFailures;
-  }
-
-  void
-  expressInterest(Face& face, const Name& name)
-  {
-    Interest i(name);
-    i.setInterestLifetime(time::milliseconds(50));
-    face.expressInterest(i,
-                         bind(&FacesFixture::onData, this),
-                         bind(&FacesFixture::onNack, this),
-                         bind(&FacesFixture::onTimeout, this));
-  }
-
-  void
-  terminate(Face& face)
-  {
-    face.getIoService().stop();
-  }
-
-  uint32_t nData;
-  uint32_t nNacks;
-  uint32_t nTimeouts;
-
-  const RegisteredPrefixId* regPrefixId;
-  const RegisteredPrefixId* regPrefixId2;
-  uint32_t nInInterests;
-  uint32_t nInInterests2;
-  uint32_t nRegFailures;
-};
-
-BOOST_FIXTURE_TEST_SUITE(TestFaces, FacesFixture)
-
-BOOST_AUTO_TEST_CASE(Unix)
-{
-  Face face;
-
-  face.expressInterest(Interest("/", time::milliseconds(1000)),
-                       bind(&FacesFixture::onData, this),
-                       bind(&FacesFixture::onNack, this),
-                       bind(&FacesFixture::onTimeout, this));
-  face.processEvents();
-  BOOST_CHECK_EQUAL(nData, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 0);
-
-  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
-                                time::milliseconds(50)),
-                       bind(&FacesFixture::onData, this),
-                       bind(&FacesFixture::onNack, this),
-                       bind(&FacesFixture::onTimeout, this));
-  face.processEvents();
-  BOOST_CHECK_EQUAL(nData, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 1);
-
-  Name veryLongName;
   for (size_t i = 0; i <= MAX_NDN_PACKET_SIZE / 10; i++) {
-    veryLongName.append("0123456789");
+    prefix.append("0123456789");
+  }
+  return prefix;
+}
+
+static std::string
+executeCommand(const std::string& cmd)
+{
+  std::string output;
+  char buf[256];
+  FILE* pipe = popen(cmd.data(), "r");
+  BOOST_REQUIRE_MESSAGE(pipe != nullptr, "cannot execute '" << cmd << "'");
+  while (fgets(buf, sizeof(buf), pipe) != nullptr) {
+    output += buf;
+  }
+  pclose(pipe);
+  return output;
+}
+
+template<typename TransportType>
+class FaceFixture : public IdentityManagementFixture
+{
+protected:
+  FaceFixture()
+    : face(TransportType::create(""), m_keyChain)
+    , sched(face.getIoService())
+  {
   }
 
-  BOOST_CHECK_THROW(do {
-    face.expressInterest(Interest(veryLongName), nullptr, nullptr, nullptr);
-    face.processEvents();
-  } while (false), Face::OversizedPacketError);
-
-  shared_ptr<Data> data = make_shared<Data>(veryLongName);
-  data->setContent(reinterpret_cast<const uint8_t*>("01234567890"), 10);
-  m_keyChain.sign(*data);
-  BOOST_CHECK_THROW(do {
-    face.put(*data);
-    face.processEvents();
-  } while (false), Face::OversizedPacketError);
-
-}
-
-BOOST_AUTO_TEST_CASE(Tcp)
-{
-  Face face("localhost");
-
-  face.expressInterest(Interest("/", time::milliseconds(1000)),
-                       bind(&FacesFixture::onData, this),
-                       bind(&FacesFixture::onNack, this),
-                       bind(&FacesFixture::onTimeout, this));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nData, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 0);
-
-  face.expressInterest(Interest("/localhost/non-existing/data/should/not/exist/anywhere",
-                                time::milliseconds(50)),
-                       bind(&FacesFixture::onData, this),
-                       bind(&FacesFixture::onNack, this),
-                       bind(&FacesFixture::onTimeout, this));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nData, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 1);
-}
-
-
-BOOST_AUTO_TEST_CASE(SetFilter)
-{
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(4),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  regPrefixId = face.setInterestFilter("/Hello/World",
-                                       bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
-                                       nullptr,
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(200),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/!")));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nInInterests, 1);
-  BOOST_CHECK_EQUAL(nTimeouts, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nData, 0);
-}
-
-BOOST_AUTO_TEST_CASE(SetTwoFilters)
-{
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(6),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  regPrefixId = face.setInterestFilter("/Hello/World",
-                                       bind(&FacesFixture::onInterest, this, ref(face), _1, _2),
-                                       nullptr,
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  regPrefixId2 = face.setInterestFilter("/Los/Angeles/Lakers",
-                                        bind(&FacesFixture::onInterest2, this, ref(face), _1, _2),
-                                        nullptr,
-                                        bind(&FacesFixture::onRegFailed, this));
-
-
-  scheduler.scheduleEvent(time::seconds(2),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/!")));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nInInterests, 1);
-  BOOST_CHECK_EQUAL(nInInterests2, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 1);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nData, 0);
-}
-
-BOOST_AUTO_TEST_CASE(SetRegexFilterError)
-{
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(4),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
-                                       bind(&FacesFixture::onInterestRegexError, this,
-                                            ref(face), _1, _2),
-                                       nullptr,
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(300),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/XXX/b/c"))); // should match
-
-  BOOST_REQUIRE_THROW(face.processEvents(), InterestFilter::Error);
-}
-
-BOOST_AUTO_TEST_CASE(SetRegexFilter)
-{
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(4),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
-                                       bind(&FacesFixture::onInterestRegex, this,
-                                            ref(face), _1, _2),
-                                       nullptr,
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(200),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a"))); // shouldn't match
-
-  scheduler.scheduleEvent(time::milliseconds(300),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b"))); // should match
-
-  scheduler.scheduleEvent(time::milliseconds(400),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/c"))); // should match
-
-  scheduler.scheduleEvent(time::milliseconds(500),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/d"))); // should not match
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nInInterests, 2);
-  BOOST_CHECK_EQUAL(nTimeouts, 4);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nData, 0);
-}
-
-class FacesFixture2 : public FacesFixture
-{
-public:
-  void
-  checkPrefix(bool shouldExist)
+  /** \brief Send an Interest from a secondary face
+   *  \param delay scheduling delay before sending Interest
+   *  \param interest the Interest
+   *  \param[out] outcome the response, initially '?', 'D' for Data, 'N' for Nack, 'T' for timeout
+   *  \return scheduled event id
+   */
+  EventId
+  sendInterest(time::nanoseconds delay, const Interest& interest, char& outcome)
   {
-    // Boost.Test fails if a child process exits with non-zero.
-    // http://stackoverflow.com/q/5325202
-    std::string output = this->executeCommand("nfdc route list | grep /Hello/World || true");
+    if (face2 == nullptr) {
+      face2 = make_unique<Face>(TransportType::create(""), face.getIoService(), m_keyChain);
+    }
 
-    if (shouldExist) {
-      BOOST_CHECK_NE(output.size(), 0);
-    }
-    else {
-      BOOST_CHECK_EQUAL(output.size(), 0);
-    }
+    outcome = '?';
+    return sched.scheduleEvent(delay, [this, interest, &outcome] {
+      face2->expressInterest(interest,
+        [&] (const Interest&, const Data&) { outcome = 'D'; },
+        [&] (const Interest&, const lp::Nack&) { outcome = 'N'; },
+        [&] (const Interest&) { outcome = 'T'; });
+    });
+  }
+
+  EventId
+  sendInterest(time::nanoseconds delay, const Interest& interest)
+  {
+    static char ignoredOutcome;
+    return sendInterest(delay, interest, ignoredOutcome);
+  }
+
+  /** \brief Stop io_service after a delay
+   *  \return scheduled event id
+   */
+  EventId
+  terminateAfter(time::nanoseconds delay)
+  {
+    return sched.scheduleEvent(delay, [this] { face.getIoService().stop(); });
   }
 
 protected:
-  std::string
-  executeCommand(const std::string& cmd)
-  {
-    std::string output;
-    char buf[256];
-    FILE* pipe = popen(cmd.c_str(), "r");
-    BOOST_REQUIRE_MESSAGE(pipe != nullptr, "cannot execute '" << cmd << "'");
-    while (fgets(buf, sizeof(buf), pipe) != nullptr) {
-      output += buf;
-    }
-    pclose(pipe);
-    return output;
-  }
+  Face face;
+  Scheduler sched;
+
+  unique_ptr<Face> face2;
 };
 
-BOOST_FIXTURE_TEST_CASE(RegisterUnregisterPrefix, FacesFixture2)
+using Transports = boost::mpl::vector<UnixTransport, TcpTransport>;
+
+BOOST_FIXTURE_TEST_SUITE(TestFace, FaceFixture<UnixTransport>)
+
+BOOST_AUTO_TEST_SUITE(Consumer)
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestData, TransportType, Transports, FaceFixture<TransportType>)
 {
-  Face face;
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(4),
-                          bind(&FacesFixture::terminate, this, ref(face)));
+  int nData = 0;
+  this->face.expressInterest(Interest("/"),
+    [&] (const Interest&, const Data&) { ++nData; },
+    [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
+    [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
 
-  regPrefixId = face.setInterestFilter(InterestFilter("/Hello/World"),
-                                       bind(&FacesFixture::onInterest, this,
-                                            ref(face), _1, _2),
-                                       nullptr,
-                                       bind(&FacesFixture::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(500),
-                          bind(&FacesFixture2::checkPrefix, this, true));
-
-  scheduler.scheduleEvent(time::seconds(1),
-    bind(static_cast<void(Face::*)(const RegisteredPrefixId*)>(&Face::unsetInterestFilter),
-         &face,
-    regPrefixId)); // shouldn't match
-
-  scheduler.scheduleEvent(time::milliseconds(2000),
-                          bind(&FacesFixture2::checkPrefix, this, false));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(nData, 1);
 }
 
-
-class FacesFixture3 : public FacesFixture2
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestNack, TransportType, Transports, FaceFixture<TransportType>)
 {
-public:
-  FacesFixture3()
-    : nRegSuccesses(0)
-    , nUnregSuccesses(0)
-    , nUnregFailures(0)
-  {
-  }
+  int nNacks = 0;
+  this->face.expressInterest(Interest("/localhost/non-existent-should-nack"),
+    [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
+    [&] (const Interest&, const lp::Nack&) { ++nNacks; },
+    [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });
 
-  void
-  onRegSucceeded()
-  {
-    ++nRegSuccesses;
-  }
-
-  void
-  onUnregSucceeded()
-  {
-    ++nUnregSuccesses;
-  }
-
-  void
-  onUnregFailed()
-  {
-    ++nUnregFailures;
-  }
-
-public:
-  uint64_t nRegSuccesses;
-  uint64_t nUnregSuccesses;
-  uint64_t nUnregFailures;
-};
-
-BOOST_FIXTURE_TEST_CASE(RegisterPrefix, FacesFixture3)
-{
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(6),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  scheduler.scheduleEvent(time::seconds(2),
-                          bind(&FacesFixture2::checkPrefix, this, true));
-
-  regPrefixId = face.registerPrefix("/Hello/World",
-                                    bind(&FacesFixture3::onRegSucceeded, this),
-                                    bind(&FacesFixture3::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::seconds(4),
-    bind(&Face::unregisterPrefix, &face,
-         regPrefixId,
-         static_cast<UnregisterPrefixSuccessCallback>(bind(&FacesFixture3::onUnregSucceeded, this)),
-         static_cast<UnregisterPrefixFailureCallback>(bind(&FacesFixture3::onUnregFailed, this))));
-
-  scheduler.scheduleEvent(time::milliseconds(6500),
-                          bind(&FacesFixture2::checkPrefix, this, false));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nRegSuccesses, 1);
-
-  BOOST_CHECK_EQUAL(nUnregFailures, 0);
-  BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(nNacks, 1);
 }
 
-BOOST_AUTO_TEST_CASE(SetRegexFilterButNoRegister)
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestTimeout, TransportType, Transports, FaceFixture<TransportType>)
 {
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(2),
-                          bind(&FacesFixture::terminate, this, ref(face)));
+  // add route toward null face so Interest would timeout instead of getting Nacked
+  executeCommand("nfdc route add /localhost/non-existent-should-timeout null://");
+  std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait for FIB update to take effect
 
-  face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
-                         bind(&FacesFixture::onInterestRegex, this,
-                              ref(face), _1, _2));
+  int nTimeouts = 0;
+  this->face.expressInterest(Interest("/localhost/non-existent-should-timeout", time::seconds(1)),
+    [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
+    [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
+    [&] (const Interest&) { ++nTimeouts; });
 
-  // prefix is not registered, and also does not match regex
-  scheduler.scheduleEvent(time::milliseconds(200),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a")));
-
-  // matches regex, but prefix is not registered
-  scheduler.scheduleEvent(time::milliseconds(300),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b")));
-
-  // matches regex, but prefix is not registered
-  scheduler.scheduleEvent(time::milliseconds(400),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/c")));
-
-  // prefix is not registered, and also does not match regex
-  scheduler.scheduleEvent(time::milliseconds(500),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/d")));
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nInInterests, 0);
-  BOOST_CHECK_EQUAL(nTimeouts, 0);
-  BOOST_CHECK_EQUAL(nNacks, 4);
-  BOOST_CHECK_EQUAL(nData, 0);
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(nTimeouts, 1);
 }
 
-
-BOOST_FIXTURE_TEST_CASE(SetRegexFilterAndRegister, FacesFixture3)
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedInterest, TransportType, Transports, FaceFixture<TransportType>)
 {
-  Face face;
-  Face face2(face.getIoService());
-  Scheduler scheduler(face.getIoService());
-  scheduler.scheduleEvent(time::seconds(4),
-                          bind(&FacesFixture::terminate, this, ref(face)));
-
-  face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
-                         bind(&FacesFixture::onInterestRegex, this,
-                              ref(face), _1, _2));
-
-  face.registerPrefix("/Hello/World",
-                      bind(&FacesFixture3::onRegSucceeded, this),
-                      bind(&FacesFixture3::onRegFailed, this));
-
-  scheduler.scheduleEvent(time::milliseconds(200),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a"))); // shouldn't match
-
-  scheduler.scheduleEvent(time::milliseconds(300),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b"))); // should match
-
-  scheduler.scheduleEvent(time::milliseconds(400),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/c"))); // should match
-
-  scheduler.scheduleEvent(time::milliseconds(500),
-                          bind(&FacesFixture::expressInterest, this,
-                               ref(face2), Name("/Hello/World/a/b/d"))); // should not match
-
-  BOOST_REQUIRE_NO_THROW(face.processEvents());
-
-  BOOST_CHECK_EQUAL(nRegFailures, 0);
-  BOOST_CHECK_EQUAL(nRegSuccesses, 1);
-
-  BOOST_CHECK_EQUAL(nInInterests, 2);
-  BOOST_CHECK_EQUAL(nTimeouts, 4);
-  BOOST_CHECK_EQUAL(nNacks, 0);
-  BOOST_CHECK_EQUAL(nData, 0);
+  BOOST_CHECK_THROW(do {
+    this->face.expressInterest(Interest(makeVeryLongName()), nullptr, nullptr, nullptr);
+    this->face.processEvents();
+  } while (false), Face::OversizedPacketError);
 }
 
+BOOST_AUTO_TEST_SUITE_END() // Consumer
+
+BOOST_AUTO_TEST_SUITE(Producer)
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegisterUnregisterPrefix, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(4));
+
+  int nRegSuccess = 0, nUnregSuccess = 0;
+  auto id = this->face.registerPrefix("/Hello/World",
+    [&] (const Name&) { ++nRegSuccess; },
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+
+  this->sched.scheduleEvent(time::seconds(1), [&nRegSuccess] {
+    BOOST_CHECK_EQUAL(nRegSuccess, 1);
+    std::string output = executeCommand("nfdc route list | grep /Hello/World");
+    BOOST_CHECK(!output.empty());
+  });
+
+  this->sched.scheduleEvent(time::seconds(2), [this, id, &nUnregSuccess] {
+    this->face.unregisterPrefix(id,
+      [&] { ++nUnregSuccess; },
+      [] (const std::string& msg) { BOOST_ERROR("unexpected unregister prefix failure: " << msg); });
+  });
+
+  this->sched.scheduleEvent(time::seconds(3), [&nUnregSuccess] {
+    BOOST_CHECK_EQUAL(nUnregSuccess, 1);
+
+    // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
+    std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
+    BOOST_CHECK(output.empty());
+  });
+
+  this->face.processEvents();
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegularFilter, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(2));
+
+  int nInterests1 = 0, nRegSuccess1 = 0, nRegSuccess2 = 0;
+  this->face.setInterestFilter("/Hello/World",
+    [&] (const InterestFilter&, const Interest&) { ++nInterests1; },
+    [&] (const Name&) { ++nRegSuccess1; },
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+  this->face.setInterestFilter("/Los/Angeles/Lakers",
+    [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); },
+    [&] (const Name&) { ++nRegSuccess2; },
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+
+  this->sched.scheduleEvent(time::milliseconds(500), [] {
+    std::string output = executeCommand("nfdc route list | grep /Hello/World");
+    BOOST_CHECK(!output.empty());
+  });
+
+  char interestOutcome;
+  this->sendInterest(time::seconds(1), Interest("/Hello/World/regular", time::milliseconds(50)), interestOutcome);
+
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(interestOutcome, 'T');
+  BOOST_CHECK_EQUAL(nInterests1, 1);
+  BOOST_CHECK_EQUAL(nRegSuccess1, 1);
+  BOOST_CHECK_EQUAL(nRegSuccess2, 1);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilter, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(2));
+
+  int nRegSuccess = 0;
+  std::set<Name> receivedInterests;
+  this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+    [&] (const InterestFilter&, const Interest& interest) { receivedInterests.insert(interest.getName()); },
+    [&] (const Name&) { ++nRegSuccess; },
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+
+  this->sched.scheduleEvent(time::milliseconds(700), [] {
+    std::string output = executeCommand("nfdc route list | grep /Hello/World");
+    BOOST_CHECK(!output.empty());
+  });
+
+  this->sendInterest(time::milliseconds(200), Interest("/Hello/World/a", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(300), Interest("/Hello/World/a/b", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(400), Interest("/Hello/World/a/b/c", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(500), Interest("/Hello/World/a/b/d", time::milliseconds(50)));
+
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(nRegSuccess, 1);
+  std::set<Name> expectedInterests{"/Hello/World/a/b", "/Hello/World/a/b/c"};
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedInterests.begin(), receivedInterests.end(),
+                                expectedInterests.begin(), expectedInterests.end());
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilterNoRegister, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(2));
+
+  // no Interest shall arrive because prefix isn't registered in forwarder
+  this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+    [&] (const InterestFilter&, const Interest& interest) { BOOST_ERROR("unexpected Interest"); });
+
+  this->sched.scheduleEvent(time::milliseconds(700), [] {
+    // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
+    std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
+    BOOST_CHECK(output.empty());
+  });
+
+  this->sendInterest(time::milliseconds(200), Interest("/Hello/World/a", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(300), Interest("/Hello/World/a/b", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(400), Interest("/Hello/World/a/b/c", time::milliseconds(50)));
+  this->sendInterest(time::milliseconds(500), Interest("/Hello/World/a/b/d", time::milliseconds(50)));
+
+  this->face.processEvents();
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(PutDataNack, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(2));
+
+  this->face.setInterestFilter("/Hello/World",
+    [&] (const InterestFilter&, const Interest& interest) {
+      if (interest.getName().at(2) == name::Component("nack")) {
+        this->face.put(makeNack(interest, lp::NackReason::NO_ROUTE));
+      }
+      else {
+        this->face.put(*makeData(interest.getName()));
+      }
+    },
+    nullptr,
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+
+  char outcome1, outcome2;
+  this->sendInterest(time::milliseconds(700), Interest("/Hello/World/data", time::milliseconds(50)), outcome1);
+  this->sendInterest(time::milliseconds(800), Interest("/Hello/World/nack", time::milliseconds(50)), outcome2);
+
+  this->face.processEvents();
+  BOOST_CHECK_EQUAL(outcome1, 'D');
+  BOOST_CHECK_EQUAL(outcome2, 'N');
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedData, TransportType, Transports, FaceFixture<TransportType>)
+{
+  this->terminateAfter(time::seconds(2));
+
+  this->face.setInterestFilter("/Hello/World",
+    [&] (const InterestFilter&, const Interest& interest) {
+      this->face.put(*makeData(makeVeryLongName(interest.getName())));
+    },
+    nullptr,
+    [] (const Name&, const std::string& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
+
+  this->sendInterest(time::seconds(1), Interest("/Hello/World/oversized", time::milliseconds(50)));
+
+  BOOST_CHECK_THROW(this->face.processEvents(), Face::OversizedPacketError);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Producer
+
+BOOST_AUTO_TEST_SUITE(IoRoutine)
+
 BOOST_AUTO_TEST_CASE(ShutdownWhileSendInProgress) // Bug #3136
 {
-  Face face;
-  face.expressInterest(Interest("/Hello/World/!"), nullptr, nullptr, nullptr);
-  BOOST_REQUIRE_NO_THROW(face.processEvents(time::seconds(1)));
+  this->face.expressInterest(Interest("/Hello/World"), nullptr, nullptr, nullptr);
+  this->face.processEvents(time::seconds(1));
 
-  face.expressInterest(Interest("/Bye/World/1"), nullptr, nullptr, nullptr);
-  face.expressInterest(Interest("/Bye/World/2"), nullptr, nullptr, nullptr);
-  face.expressInterest(Interest("/Bye/World/3"), nullptr, nullptr, nullptr);
-  face.shutdown();
+  this->face.expressInterest(Interest("/Bye/World/1"), nullptr, nullptr, nullptr);
+  this->face.expressInterest(Interest("/Bye/World/2"), nullptr, nullptr, nullptr);
+  this->face.expressInterest(Interest("/Bye/World/3"), nullptr, nullptr, nullptr);
+  this->face.shutdown();
 
-  BOOST_REQUIRE_NO_THROW(face.processEvents(time::seconds(1)));
-  // should not segfault
+  this->face.processEvents(time::seconds(1)); // should not segfault
+  BOOST_CHECK(true);
 }
 
 BOOST_AUTO_TEST_CASE(LargeDelayBetweenFaceConstructorAndProcessEvents) // Bug #2742
 {
-  ndn::Face face;
-
-  ::sleep(5); // simulate setup workload
-
-  BOOST_CHECK_NO_THROW(face.processEvents(time::seconds(1)));
+  std::this_thread::sleep_for(std::chrono::seconds(5)); // simulate setup workload
+  this->face.processEvents(time::seconds(1)); // should not throw
+  BOOST_CHECK(true);
 }
 
 BOOST_AUTO_TEST_CASE(ProcessEventsBlocksForeverWhenNothingScheduled) // Bug #3957
 {
-  ndn::Face face;
   std::mutex m;
   std::condition_variable cv;
   bool processEventsFinished = false;
 
   std::thread faceThread([&] {
-      face.processEvents();
+    this->face.processEvents();
 
-      processEventsFinished = true;
-      std::lock_guard<std::mutex> lk(m);
-      cv.notify_one();
-    });
+    processEventsFinished = true;
+    std::lock_guard<std::mutex> lk(m);
+    cv.notify_one();
+  });
 
   {
     std::unique_lock<std::mutex> lk(m);
@@ -593,12 +375,14 @@
 
   BOOST_CHECK_EQUAL(processEventsFinished, true);
   if (!processEventsFinished) {
-    face.shutdown();
+    this->face.shutdown();
   }
   faceThread.join();
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // IoRoutine
+
+BOOST_AUTO_TEST_SUITE_END() // TestFace
 
 } // namespace tests
 } // namespace ndn
diff --git a/tests/unit-tests/make-interest-data.cpp b/tests/make-interest-data.cpp
similarity index 100%
rename from tests/unit-tests/make-interest-data.cpp
rename to tests/make-interest-data.cpp
diff --git a/tests/unit-tests/make-interest-data.hpp b/tests/make-interest-data.hpp
similarity index 94%
rename from tests/unit-tests/make-interest-data.hpp
rename to tests/make-interest-data.hpp
index eb208d1..8fc5545 100644
--- a/tests/unit-tests/make-interest-data.hpp
+++ b/tests/make-interest-data.hpp
@@ -19,8 +19,8 @@
  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
  */
 
-#ifndef NDN_TESTS_UNIT_TESTS_MAKE_INTEREST_DATA_HPP
-#define NDN_TESTS_UNIT_TESTS_MAKE_INTEREST_DATA_HPP
+#ifndef NDN_TESTS_MAKE_INTEREST_DATA_HPP
+#define NDN_TESTS_MAKE_INTEREST_DATA_HPP
 
 #include "interest.hpp"
 #include "data.hpp"
@@ -101,4 +101,4 @@
 } // namespace tests
 } // namespace ndn
 
-#endif // NDN_TESTS_UNIT_TESTS_MAKE_INTEREST_DATA_HPP
+#endif // NDN_TESTS_MAKE_INTEREST_DATA_HPP
diff --git a/tests/unit-tests/ims/in-memory-storage-fifo.t.cpp b/tests/unit-tests/ims/in-memory-storage-fifo.t.cpp
index 7455ec0..a873de1 100644
--- a/tests/unit-tests/ims/in-memory-storage-fifo.t.cpp
+++ b/tests/unit-tests/ims/in-memory-storage-fifo.t.cpp
@@ -22,7 +22,7 @@
 #include "ims/in-memory-storage-fifo.hpp"
 
 #include "boost-test.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace tests {
diff --git a/tests/unit-tests/ims/in-memory-storage-lfu.t.cpp b/tests/unit-tests/ims/in-memory-storage-lfu.t.cpp
index b3462de..1fa8b83 100644
--- a/tests/unit-tests/ims/in-memory-storage-lfu.t.cpp
+++ b/tests/unit-tests/ims/in-memory-storage-lfu.t.cpp
@@ -22,7 +22,7 @@
 #include "ims/in-memory-storage-lfu.hpp"
 
 #include "boost-test.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace tests {
diff --git a/tests/unit-tests/ims/in-memory-storage-lru.t.cpp b/tests/unit-tests/ims/in-memory-storage-lru.t.cpp
index f371f9b..80c59d5 100644
--- a/tests/unit-tests/ims/in-memory-storage-lru.t.cpp
+++ b/tests/unit-tests/ims/in-memory-storage-lru.t.cpp
@@ -22,7 +22,7 @@
 #include "ims/in-memory-storage-lru.hpp"
 
 #include "boost-test.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace tests {
diff --git a/tests/unit-tests/ims/in-memory-storage-persistent.t.cpp b/tests/unit-tests/ims/in-memory-storage-persistent.t.cpp
index 69c0d7e..9be6430 100644
--- a/tests/unit-tests/ims/in-memory-storage-persistent.t.cpp
+++ b/tests/unit-tests/ims/in-memory-storage-persistent.t.cpp
@@ -22,7 +22,7 @@
 #include "ims/in-memory-storage-persistent.hpp"
 
 #include "boost-test.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace tests {
diff --git a/tests/unit-tests/ims/in-memory-storage.t.cpp b/tests/unit-tests/ims/in-memory-storage.t.cpp
index 3689c53..67d87f2 100644
--- a/tests/unit-tests/ims/in-memory-storage.t.cpp
+++ b/tests/unit-tests/ims/in-memory-storage.t.cpp
@@ -28,7 +28,7 @@
 #include "util/sha256.hpp"
 
 #include "boost-test.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 #include "../unit-test-time-fixture.hpp"
 
 #include <boost/mpl/list.hpp>
diff --git a/tests/unit-tests/interest-filter.t.cpp b/tests/unit-tests/interest-filter.t.cpp
index e39f8dd..26be797 100644
--- a/tests/unit-tests/interest-filter.t.cpp
+++ b/tests/unit-tests/interest-filter.t.cpp
@@ -21,12 +21,12 @@
 
 #include "interest-filter.hpp"
 #include "data.hpp"
+#include "encoding/buffer-stream.hpp"
 #include "security/signature-sha256-with-rsa.hpp"
 #include "security/digest-sha256.hpp"
-#include "encoding/buffer-stream.hpp"
+#include "util/dummy-client-face.hpp"
 
 #include "boost-test.hpp"
-#include "identity-management-fixture.hpp"
 
 namespace ndn {
 namespace tests {
@@ -52,6 +52,15 @@
   BOOST_CHECK_EQUAL(InterestFilter("/a", "<b><>+").doesMatch("/a/b/c"), true);
 }
 
+BOOST_AUTO_TEST_CASE(RegexConvertToName)
+{
+  util::DummyClientFace face;
+  face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
+    [] (const Name&, const Interest&) { BOOST_ERROR("unexpected Interest"); });
+  face.processEvents(time::milliseconds(1));
+  BOOST_CHECK_THROW(face.receive(Interest("/Hello/World/a/b/c")), InterestFilter::Error);
+}
+
 BOOST_AUTO_TEST_SUITE_END() // TestInterestFilter
 
 } // namespace tests
diff --git a/tests/unit-tests/mgmt/dispatcher.t.cpp b/tests/unit-tests/mgmt/dispatcher.t.cpp
index 536616c..b9577cb 100644
--- a/tests/unit-tests/mgmt/dispatcher.t.cpp
+++ b/tests/unit-tests/mgmt/dispatcher.t.cpp
@@ -24,9 +24,8 @@
 #include "util/dummy-client-face.hpp"
 
 #include "boost-test.hpp"
-#include "identity-management-fixture.hpp"
+#include "make-interest-data.hpp"
 #include "../identity-management-time-fixture.hpp"
-#include "../make-interest-data.hpp"
 
 namespace ndn {
 namespace mgmt {
diff --git a/tests/unit-tests/mgmt/nfd/controller.t.cpp b/tests/unit-tests/mgmt/nfd/controller.t.cpp
index 423499a..92fcedd 100644
--- a/tests/unit-tests/mgmt/nfd/controller.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/controller.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -22,10 +22,8 @@
 #include "mgmt/nfd/controller.hpp"
 #include "mgmt/nfd/control-response.hpp"
 
-#include <boost/tuple/tuple.hpp>
-
 #include "controller-fixture.hpp"
-#include "../../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace nfd {
diff --git a/tests/unit-tests/mgmt/nfd/status-dataset.t.cpp b/tests/unit-tests/mgmt/nfd/status-dataset.t.cpp
index aadb2c4..13cd203 100644
--- a/tests/unit-tests/mgmt/nfd/status-dataset.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/status-dataset.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,7 +23,7 @@
 #include "mgmt/nfd/controller.hpp"
 
 #include "controller-fixture.hpp"
-#include "../../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace nfd {
diff --git a/tests/unit-tests/mgmt/status-dataset-context.t.cpp b/tests/unit-tests/mgmt/status-dataset-context.t.cpp
index cff721b..be7b198 100644
--- a/tests/unit-tests/mgmt/status-dataset-context.t.cpp
+++ b/tests/unit-tests/mgmt/status-dataset-context.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,7 +22,7 @@
 #include "mgmt/status-dataset-context.hpp"
 
 #include "boost-test.hpp"
-#include "unit-tests/make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace mgmt {
diff --git a/tests/unit-tests/security/v2/validation-policy-command-interest.t.cpp b/tests/unit-tests/security/v2/validation-policy-command-interest.t.cpp
index 293bf26..887214a 100644
--- a/tests/unit-tests/security/v2/validation-policy-command-interest.t.cpp
+++ b/tests/unit-tests/security/v2/validation-policy-command-interest.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -27,7 +27,7 @@
 
 #include "boost-test.hpp"
 #include "validator-fixture.hpp"
-#include "unit-tests/make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 #include <boost/lexical_cast.hpp>
 #include <boost/mpl/vector.hpp>
diff --git a/tests/unit-tests/security/validator-config.t.cpp b/tests/unit-tests/security/validator-config.t.cpp
index 74c29ae..e2fbda1 100644
--- a/tests/unit-tests/security/validator-config.t.cpp
+++ b/tests/unit-tests/security/validator-config.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -20,21 +20,18 @@
  */
 
 #include "security/validator-config.hpp"
-
 #include "security/signing-helpers.hpp"
+#include "util/dummy-client-face.hpp"
 #include "util/io.hpp"
 #include "util/scheduler.hpp"
-#include "util/dummy-client-face.hpp"
-#include "lp/tags.hpp"
 #include "lp/nack.hpp"
+#include "lp/tags.hpp"
 
-#include <boost/asio.hpp>
-#include <boost/logic/tribool.hpp>
-
-#include "identity-management-fixture.hpp"
-#include "../identity-management-time-fixture.hpp"
-#include "../make-interest-data.hpp"
 #include "boost-test.hpp"
+#include "make-interest-data.hpp"
+#include "../identity-management-time-fixture.hpp"
+
+#include <boost/logic/tribool.hpp>
 
 namespace ndn {
 namespace security {
diff --git a/tests/unit-tests/security/validator-null.t.cpp b/tests/unit-tests/security/validator-null.t.cpp
index b4f4102..07c317f 100644
--- a/tests/unit-tests/security/validator-null.t.cpp
+++ b/tests/unit-tests/security/validator-null.t.cpp
@@ -23,7 +23,7 @@
 
 #include "boost-test.hpp"
 #include "identity-management-fixture.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace security {
diff --git a/tests/unit-tests/security/validator.t.cpp b/tests/unit-tests/security/validator.t.cpp
index 6f22c5a..7550eb3 100644
--- a/tests/unit-tests/security/validator.t.cpp
+++ b/tests/unit-tests/security/validator.t.cpp
@@ -23,7 +23,7 @@
 
 #include "boost-test.hpp"
 #include "identity-management-fixture.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 namespace ndn {
 namespace security {
diff --git a/tests/unit-tests/security/verification-helpers.t.cpp b/tests/unit-tests/security/verification-helpers.t.cpp
index 0f0809e..d1654d7 100644
--- a/tests/unit-tests/security/verification-helpers.t.cpp
+++ b/tests/unit-tests/security/verification-helpers.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -25,7 +25,7 @@
 
 #include "boost-test.hpp"
 #include "identity-management-fixture.hpp"
-#include "../make-interest-data.hpp"
+#include "make-interest-data.hpp"
 
 #include <boost/mpl/list.hpp>
 
diff --git a/tests/unit-tests/util/notification-subscriber.t.cpp b/tests/unit-tests/util/notification-subscriber.t.cpp
index 30924f3..aef46a3 100644
--- a/tests/unit-tests/util/notification-subscriber.t.cpp
+++ b/tests/unit-tests/util/notification-subscriber.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
@@ -26,12 +26,12 @@
  */
 
 #include "util/notification-subscriber.hpp"
-#include "simple-notification.hpp"
 #include "util/dummy-client-face.hpp"
 
-#include "../identity-management-time-fixture.hpp"
-#include "../make-interest-data.hpp"
 #include "boost-test.hpp"
+#include "make-interest-data.hpp"
+#include "simple-notification.hpp"
+#include "../identity-management-time-fixture.hpp"
 
 namespace ndn {
 namespace util {
diff --git a/tests/unit-tests/util/segment-fetcher.t.cpp b/tests/unit-tests/util/segment-fetcher.t.cpp
index 09eb212..d80f1ae 100644
--- a/tests/unit-tests/util/segment-fetcher.t.cpp
+++ b/tests/unit-tests/util/segment-fetcher.t.cpp
@@ -20,15 +20,15 @@
  */
 
 #include "util/segment-fetcher.hpp"
-#include "lp/nack-header.hpp"
 #include "data.hpp"
 #include "encoding/block.hpp"
+#include "lp/nack-header.hpp"
+#include "util/dummy-client-face.hpp"
 
 #include "boost-test.hpp"
-#include "util/dummy-client-face.hpp"
+#include "dummy-validator.hpp"
+#include "make-interest-data.hpp"
 #include "../identity-management-time-fixture.hpp"
-#include "../make-interest-data.hpp"
-#include "../../dummy-validator.hpp"
 
 namespace ndn {
 namespace util {
diff --git a/tests/wscript b/tests/wscript
index af4b422..0221a6e 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -13,10 +13,10 @@
         use='ndn-cxx BOOST',
         includes='.')
 
-    # core modules that can be shared between unit and integrated tests
+    # core objects that can be shared between unit and integrated tests
     bld(features="cxx",
         target="boost-tests-base",
-        source="identity-management-fixture.cpp",
+        source=bld.path.ant_glob(['*.cpp'], excl=['main.cpp']),
         use='ndn-cxx tests-base BOOST',
         includes='.',
         install_path=None)