core+daemon: eliminate scheduler::{schedule,cancel} wrappers

Also move core/global-io.hpp to daemon/global.hpp

Refs: #4528, #4883
Change-Id: I0b99029f1a19d7451aab57099cd3303b7eb42ff3
diff --git a/tests/daemon/face/channel-fixture.hpp b/tests/daemon/face/channel-fixture.hpp
index 7efedfd..8f94a09 100644
--- a/tests/daemon/face/channel-fixture.hpp
+++ b/tests/daemon/face/channel-fixture.hpp
@@ -27,7 +27,8 @@
 #define NFD_TESTS_DAEMON_FACE_CHANNEL_FIXTURE_HPP
 
 #include "face/channel.hpp"
-#include "tests/limited-io.hpp"
+
+#include "tests/daemon/limited-io.hpp"
 
 #include <type_traits>
 
diff --git a/tests/daemon/face/ethernet-fixture.hpp b/tests/daemon/face/ethernet-fixture.hpp
index 993352d..0a75fcc 100644
--- a/tests/daemon/face/ethernet-fixture.hpp
+++ b/tests/daemon/face/ethernet-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 #include "face/multicast-ethernet-transport.hpp"
 #include "face/unicast-ethernet-transport.hpp"
 
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 #include "test-netif.hpp"
 
 namespace nfd {
diff --git a/tests/daemon/face/multicast-ethernet-transport.t.cpp b/tests/daemon/face/multicast-ethernet-transport.t.cpp
index d4e1fce..220274c 100644
--- a/tests/daemon/face/multicast-ethernet-transport.t.cpp
+++ b/tests/daemon/face/multicast-ethernet-transport.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -27,6 +27,8 @@
 
 #include "ethernet-fixture.hpp"
 
+#include "daemon/global.hpp"
+
 namespace nfd {
 namespace face {
 namespace tests {
@@ -66,7 +68,7 @@
   BOOST_CHECK_EQUAL(transport->getState(), TransportState::UP);
 
   // simulate 'ip link set IFNAME down'
-  scheduler::schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::DOWN); });
+  getScheduler().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);
@@ -76,8 +78,8 @@
   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); });
+  getScheduler().schedule(10_ms, [=] { netif->setState(ndn::net::InterfaceState::NO_CARRIER); });
+  getScheduler().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);
diff --git a/tests/daemon/face/multicast-udp-transport-fixture.hpp b/tests/daemon/face/multicast-udp-transport-fixture.hpp
index 5959821..06455c7 100644
--- a/tests/daemon/face/multicast-udp-transport-fixture.hpp
+++ b/tests/daemon/face/multicast-udp-transport-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 #include "face/face.hpp"
 
 #include "dummy-receive-link-service.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index d349cf9..3c00134 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -27,7 +27,7 @@
 
 #include "face-system-fixture.hpp"
 #include "factory-test-common.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/face/tcp-transport-fixture.hpp b/tests/daemon/face/tcp-transport-fixture.hpp
index 0cfae44..65a4d24 100644
--- a/tests/daemon/face/tcp-transport-fixture.hpp
+++ b/tests/daemon/face/tcp-transport-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 #include "face/face.hpp"
 
 #include "dummy-receive-link-service.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/face/test-netif.cpp b/tests/daemon/face/test-netif.cpp
index c1a734d..a19623f 100644
--- a/tests/daemon/face/test-netif.cpp
+++ b/tests/daemon/face/test-netif.cpp
@@ -24,7 +24,7 @@
  */
 
 #include "test-netif.hpp"
-#include "core/global-io.hpp"
+#include "daemon/global.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/face/unicast-udp-transport-fixture.hpp b/tests/daemon/face/unicast-udp-transport-fixture.hpp
index e30a6a2..b269a71 100644
--- a/tests/daemon/face/unicast-udp-transport-fixture.hpp
+++ b/tests/daemon/face/unicast-udp-transport-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 #include "face/face.hpp"
 
 #include "dummy-receive-link-service.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/face/unix-stream-transport-fixture.hpp b/tests/daemon/face/unix-stream-transport-fixture.hpp
index 634bb9a..d131a00 100644
--- a/tests/daemon/face/unix-stream-transport-fixture.hpp
+++ b/tests/daemon/face/unix-stream-transport-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 #include "face/face.hpp"
 
 #include "dummy-receive-link-service.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 #include <boost/filesystem.hpp>
 
diff --git a/tests/daemon/face/websocket-transport-fixture.hpp b/tests/daemon/face/websocket-transport-fixture.hpp
index 374f922..38ab81c 100644
--- a/tests/daemon/face/websocket-transport-fixture.hpp
+++ b/tests/daemon/face/websocket-transport-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 #include "face/face.hpp"
 
 #include "dummy-receive-link-service.hpp"
-#include "tests/limited-io.hpp"
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace face {
diff --git a/tests/daemon/fw/asf-measurements.t.cpp b/tests/daemon/fw/asf-measurements.t.cpp
index cc4c9e4..71491b7 100644
--- a/tests/daemon/fw/asf-measurements.t.cpp
+++ b/tests/daemon/fw/asf-measurements.t.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "fw/asf-measurements.hpp"
+#include "daemon/global.hpp"
 
 #include "tests/daemon/face/dummy-face.hpp"
 #include "tests/test-common.hpp"
@@ -85,7 +86,7 @@
 {
   FaceInfo info;
 
-  scheduler::EventId id = scheduler::schedule(time::seconds(1), []{});
+  auto id = getScheduler().schedule(1_s, []{});
   ndn::Name interestName("/ndn/interest");
 
   // Receive Interest and forward to next hop; should update RTO information
diff --git a/tests/daemon/fw/best-route-strategy2.t.cpp b/tests/daemon/fw/best-route-strategy2.t.cpp
index 80e2603..83f9903 100644
--- a/tests/daemon/fw/best-route-strategy2.t.cpp
+++ b/tests/daemon/fw/best-route-strategy2.t.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "fw/best-route-strategy2.hpp"
+#include "daemon/global.hpp"
 
 #include "tests/test-common.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
@@ -108,17 +109,17 @@
     size_t nSent = strategy.sendInterestHistory.size();
     if (nSent > nSentLast) {
       BOOST_CHECK_EQUAL(nSent - nSentLast, 1);
-      time::steady_clock::TimePoint timeSent = time::steady_clock::now();
+      auto timeSent = time::steady_clock::now();
       BOOST_CHECK_GE(timeSent - timeSentLast, TICK * 8);
       nSentLast = nSent;
       timeSentLast = timeSent;
     }
 
-    retxFrom4Evt = scheduler::schedule(TICK * 5, periodicalRetxFrom4);
+    retxFrom4Evt = getScheduler().schedule(TICK * 5, periodicalRetxFrom4);
   };
   periodicalRetxFrom4();
   this->advanceClocks(TICK, BestRouteStrategy2::RETX_SUPPRESSION_MAX * 16);
-  scheduler::cancel(retxFrom4Evt);
+  retxFrom4Evt.cancel();
 
   // nexthops for accepted retransmissions: follow FIB cost,
   // later forward to an eligible upstream with earliest out-record
diff --git a/tests/daemon/fw/forwarder.t.cpp b/tests/daemon/fw/forwarder.t.cpp
index 2c7c1d2..60c8ea4 100644
--- a/tests/daemon/fw/forwarder.t.cpp
+++ b/tests/daemon/fw/forwarder.t.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "fw/forwarder.hpp"
+#include "daemon/global.hpp"
 
 #include "tests/test-common.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
@@ -545,7 +546,7 @@
   face2->afterSend.connect([face1, face2] (uint32_t pktType) {
     if (pktType == tlv::Interest) {
       auto interest = make_shared<Interest>(face2->sentInterests.back());
-      scheduler::schedule(time::milliseconds(170), [face1, interest] { face1->receiveInterest(*interest); });
+      getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest); });
     }
   });
 
diff --git a/tests/daemon/fw/multicast-strategy.t.cpp b/tests/daemon/fw/multicast-strategy.t.cpp
index 1ee1ae9..e3ed88b 100644
--- a/tests/daemon/fw/multicast-strategy.t.cpp
+++ b/tests/daemon/fw/multicast-strategy.t.cpp
@@ -24,10 +24,11 @@
  */
 
 #include "fw/multicast-strategy.hpp"
-#include "strategy-tester.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
+#include "daemon/global.hpp"
 
+#include "tests/daemon/face/dummy-face.hpp"
 #include "tests/test-common.hpp"
+#include "strategy-tester.hpp"
 
 namespace nfd {
 namespace fw {
@@ -108,17 +109,17 @@
     if (nSent > nSentLast) {
       // Multicast strategy should multicast the interest to other two faces
       BOOST_CHECK_EQUAL(nSent - nSentLast, 2);
-      time::steady_clock::TimePoint timeSent = time::steady_clock::now();
+      auto timeSent = time::steady_clock::now();
       BOOST_CHECK_GE(timeSent - timeSentLast, TICK * 8);
       nSentLast = nSent;
       timeSentLast = timeSent;
     }
 
-    retxFrom4Evt = scheduler::schedule(TICK * 5, periodicalRetxFrom4);
+    retxFrom4Evt = getScheduler().schedule(TICK * 5, periodicalRetxFrom4);
   };
   periodicalRetxFrom4();
   this->advanceClocks(TICK, MulticastStrategy::RETX_SUPPRESSION_MAX * 16);
-  scheduler::cancel(retxFrom4Evt);
+  retxFrom4Evt.cancel();
 }
 
 BOOST_AUTO_TEST_CASE(RejectLoopback)
diff --git a/tests/daemon/fw/ncc-strategy.t.cpp b/tests/daemon/fw/ncc-strategy.t.cpp
index 1b71aa2..4044251 100644
--- a/tests/daemon/fw/ncc-strategy.t.cpp
+++ b/tests/daemon/fw/ncc-strategy.t.cpp
@@ -24,12 +24,10 @@
  */
 
 #include "fw/ncc-strategy.hpp"
+
+#include "tests/daemon/face/dummy-face.hpp"
 #include "strategy-tester.hpp"
 #include "topology-tester.hpp"
-#include "tests/daemon/face/dummy-face.hpp"
-#include "tests/limited-io.hpp"
-
-#include "tests/test-common.hpp"
 
 namespace nfd {
 namespace fw {
diff --git a/tests/daemon/fw/strategy-nack-return.t.cpp b/tests/daemon/fw/strategy-nack-return.t.cpp
index 86c47f6..3d61452 100644
--- a/tests/daemon/fw/strategy-nack-return.t.cpp
+++ b/tests/daemon/fw/strategy-nack-return.t.cpp
@@ -31,12 +31,11 @@
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/limited-io.hpp"
 #include "choose-strategy.hpp"
 #include "strategy-tester.hpp"
 #include "topology-tester.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
+
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
diff --git a/tests/daemon/fw/strategy-no-route.t.cpp b/tests/daemon/fw/strategy-no-route.t.cpp
index 3c5be6b..6e8aa8a 100644
--- a/tests/daemon/fw/strategy-no-route.t.cpp
+++ b/tests/daemon/fw/strategy-no-route.t.cpp
@@ -34,11 +34,10 @@
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/limited-io.hpp"
 #include "choose-strategy.hpp"
 #include "strategy-tester.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
+
 #include <boost/mpl/copy_if.hpp>
 #include <boost/mpl/vector.hpp>
 
diff --git a/tests/daemon/fw/strategy-scope-control.t.cpp b/tests/daemon/fw/strategy-scope-control.t.cpp
index 984c792..c97e8ab 100644
--- a/tests/daemon/fw/strategy-scope-control.t.cpp
+++ b/tests/daemon/fw/strategy-scope-control.t.cpp
@@ -35,11 +35,10 @@
 #include "fw/multicast-strategy.hpp"
 #include "fw/ncc-strategy.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/limited-io.hpp"
 #include "choose-strategy.hpp"
 #include "strategy-tester.hpp"
 #include "tests/daemon/face/dummy-face.hpp"
+
 #include <boost/mpl/copy_if.hpp>
 #include <boost/mpl/vector.hpp>
 
diff --git a/tests/daemon/fw/strategy-tester.hpp b/tests/daemon/fw/strategy-tester.hpp
index 5b5c98d..f2ac93d 100644
--- a/tests/daemon/fw/strategy-tester.hpp
+++ b/tests/daemon/fw/strategy-tester.hpp
@@ -27,7 +27,8 @@
 #define NFD_TESTS_DAEMON_FW_STRATEGY_TESTER_HPP
 
 #include "fw/strategy.hpp"
-#include "tests/limited-io.hpp"
+
+#include "tests/daemon/limited-io.hpp"
 
 namespace nfd {
 namespace fw {
diff --git a/tests/daemon/fw/topology-tester.cpp b/tests/daemon/fw/topology-tester.cpp
index 15bbc3c..c401aef 100644
--- a/tests/daemon/fw/topology-tester.cpp
+++ b/tests/daemon/fw/topology-tester.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "topology-tester.hpp"
+#include "daemon/global.hpp"
 #include "face/generic-link-service.hpp"
 
 #include <ndn-cxx/encoding/encoding-buffer-fwd.hpp>
@@ -98,7 +99,7 @@
 void
 TopologyLink::scheduleReceive(InternalTransportBase* recipient, const Block& packet)
 {
-  scheduler::schedule(m_delay, [packet, recipient] {
+  getScheduler().schedule(m_delay, [packet, recipient] {
     recipient->receiveFromLink(packet);
   });
 }
@@ -271,8 +272,9 @@
   face.expressInterest(*interest, nullptr, nullptr, nullptr);
 
   if (n > 1) {
-    scheduler::schedule(interval,
-                        [=, &face] { addIntervalConsumer(face, prefix, interval, n - 1, seq); });
+    getScheduler().schedule(interval, [=, &face] {
+      addIntervalConsumer(face, prefix, interval, n - 1, seq);
+    });
   }
 }
 
diff --git a/tests/daemon/global.t.cpp b/tests/daemon/global.t.cpp
new file mode 100644
index 0000000..bdde1ba
--- /dev/null
+++ b/tests/daemon/global.t.cpp
@@ -0,0 +1,143 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "daemon/global.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/rib-io-fixture.hpp"
+
+#include <thread>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TestGlobal, BaseFixture)
+
+BOOST_AUTO_TEST_CASE(ThreadLocalIoService)
+{
+  boost::asio::io_service* s1 = &getGlobalIoService();
+  boost::asio::io_service* s2 = nullptr;
+
+  std::thread t([&s2] { s2 = &getGlobalIoService(); });
+  t.join();
+
+  BOOST_CHECK(s1 != nullptr);
+  BOOST_CHECK(s2 != nullptr);
+  BOOST_CHECK(s1 != s2);
+}
+
+BOOST_AUTO_TEST_CASE(ThreadLocalScheduler)
+{
+  scheduler::Scheduler* s1 = &getScheduler();
+  scheduler::Scheduler* s2 = nullptr;
+
+  std::thread t([&s2] { s2 = &getScheduler(); });
+  t.join();
+
+  BOOST_CHECK(s1 != nullptr);
+  BOOST_CHECK(s2 != nullptr);
+  BOOST_CHECK(s1 != s2);
+}
+
+BOOST_FIXTURE_TEST_CASE(MainRibIoService, RibIoFixture)
+{
+  boost::asio::io_service* mainIo = &g_io;
+  boost::asio::io_service* ribIo = g_ribIo;
+
+  BOOST_CHECK(mainIo != ribIo);
+  BOOST_CHECK(&getGlobalIoService() == mainIo);
+  BOOST_CHECK(&getMainIoService() == mainIo);
+  BOOST_CHECK(&getRibIoService() == ribIo);
+  auto mainThreadId = std::this_thread::get_id();
+
+  runOnRibIoService([&] {
+    BOOST_CHECK(mainThreadId != std::this_thread::get_id());
+    BOOST_CHECK(&getGlobalIoService() == ribIo);
+    BOOST_CHECK(&getMainIoService() == mainIo);
+    BOOST_CHECK(&getRibIoService() == ribIo);
+  });
+
+  runOnRibIoService([&] {
+    runOnMainIoService([&] {
+      BOOST_CHECK(mainThreadId == std::this_thread::get_id());
+      BOOST_CHECK(&getGlobalIoService() == mainIo);
+      BOOST_CHECK(&getMainIoService() == mainIo);
+      BOOST_CHECK(&getRibIoService() == ribIo);
+    });
+  });
+}
+
+BOOST_FIXTURE_TEST_CASE(PollInAllThreads, RibIoFixture)
+{
+  bool hasRibRun = false;
+  runOnRibIoService([&] { hasRibRun = true; });
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+  BOOST_CHECK_EQUAL(hasRibRun, false);
+
+  poll();
+  BOOST_CHECK_EQUAL(hasRibRun, true);
+
+  hasRibRun = false;
+  bool hasMainRun = false;
+  runOnMainIoService([&] {
+    hasMainRun = true;
+    runOnRibIoService([&] { hasRibRun = true; });
+  });
+  BOOST_CHECK_EQUAL(hasMainRun, false);
+  BOOST_CHECK_EQUAL(hasRibRun, false);
+
+  poll();
+  BOOST_CHECK_EQUAL(hasMainRun, true);
+  BOOST_CHECK_EQUAL(hasRibRun, true);
+}
+
+BOOST_FIXTURE_TEST_CASE(AdvanceClocks, RibIoTimeFixture)
+{
+  bool hasRibRun = false;
+  runOnRibIoService([&] { hasRibRun = true; });
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+  BOOST_CHECK_EQUAL(hasRibRun, false);
+
+  advanceClocks(1_ns, 1);
+  BOOST_CHECK_EQUAL(hasRibRun, true);
+
+  hasRibRun = false;
+  bool hasMainRun = false;
+  getScheduler().schedule(250_ms, [&] {
+    hasMainRun = true;
+    runOnRibIoService([&] { hasRibRun = true; });
+  });
+  BOOST_CHECK_EQUAL(hasMainRun, false);
+  BOOST_CHECK_EQUAL(hasRibRun, false);
+
+  advanceClocks(260_ms, 2);
+  BOOST_CHECK_EQUAL(hasMainRun, true);
+  BOOST_CHECK_EQUAL(hasRibRun, true);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestGlobal
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/limited-io.cpp b/tests/daemon/limited-io.cpp
new file mode 100644
index 0000000..2779b24
--- /dev/null
+++ b/tests/daemon/limited-io.cpp
@@ -0,0 +1,116 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "limited-io.hpp"
+#include "core/logger.hpp"
+#include "daemon/global.hpp"
+
+#include <boost/exception/diagnostic_information.hpp>
+
+namespace nfd {
+namespace tests {
+
+NFD_LOG_INIT(tests.LimitedIo);
+
+const int LimitedIo::UNLIMITED_OPS = std::numeric_limits<int>::max();
+const time::nanoseconds LimitedIo::UNLIMITED_TIME = time::nanoseconds::min();
+
+LimitedIo::LimitedIo(UnitTestTimeFixture* uttf)
+  : m_uttf(uttf)
+{
+}
+
+LimitedIo::StopReason
+LimitedIo::run(int nOpsLimit, const time::nanoseconds& timeLimit, const time::nanoseconds& tick)
+{
+  BOOST_ASSERT(!m_isRunning);
+
+  if (nOpsLimit <= 0) {
+    return EXCEED_OPS;
+  }
+
+  m_isRunning = true;
+
+  m_reason = NO_WORK;
+  m_nOpsRemaining = nOpsLimit;
+  if (timeLimit >= 0_ns) {
+    m_timeout = getScheduler().schedule(timeLimit, [this] { afterTimeout(); });
+  }
+
+  try {
+    if (m_uttf == nullptr) {
+      getGlobalIoService().run();
+    }
+    else {
+      // timeLimit is enforced by afterTimeout
+      m_uttf->advanceClocks(tick, time::nanoseconds::max());
+    }
+  }
+  catch (const StopException&) {
+  }
+  catch (const std::exception& ex) {
+    NFD_LOG_ERROR("LimitedIo::run: " << boost::diagnostic_information(ex));
+    m_reason = EXCEPTION;
+    m_lastException = std::current_exception();
+  }
+
+  getGlobalIoService().reset();
+  m_timeout.cancel();
+  m_isRunning = false;
+
+  return m_reason;
+}
+
+void
+LimitedIo::afterOp()
+{
+  if (!m_isRunning) {
+    // Do not proceed further if .afterOp() is invoked out of .run(),
+    return;
+  }
+
+  --m_nOpsRemaining;
+
+  if (m_nOpsRemaining <= 0) {
+    m_reason = EXCEED_OPS;
+    getGlobalIoService().stop();
+    if (m_uttf != nullptr) {
+      NDN_THROW(StopException());
+    }
+  }
+}
+
+void
+LimitedIo::afterTimeout()
+{
+  m_reason = EXCEED_TIME;
+  getGlobalIoService().stop();
+  if (m_uttf != nullptr) {
+    NDN_THROW(StopException());
+  }
+}
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/limited-io.hpp b/tests/daemon/limited-io.hpp
new file mode 100644
index 0000000..7e7ecc4
--- /dev/null
+++ b/tests/daemon/limited-io.hpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TESTS_DAEMON_LIMITED_IO_HPP
+#define NFD_TESTS_DAEMON_LIMITED_IO_HPP
+
+#include "tests/test-common.hpp"
+
+#include <exception>
+
+namespace nfd {
+namespace tests {
+
+/** \brief provides IO operations limit and/or time limit for unit testing
+ *
+ *  \warning LimitedIo is incompatible with RibIoFixture
+ */
+class LimitedIo : noncopyable
+{
+public:
+  explicit
+  LimitedIo(UnitTestTimeFixture* uttf = nullptr);
+
+  /// indicates why run() returns
+  enum StopReason {
+    /// g_io.run() returns normally because there's no work to do
+    NO_WORK,
+    /// .afterOp() has been invoked nOpsLimit times
+    EXCEED_OPS,
+    /// nTimeLimit has elapsed
+    EXCEED_TIME,
+    /// an exception is thrown
+    EXCEPTION
+  };
+
+  /** \brief g_io.run() with operation count and/or time limit
+   *  \param nOpsLimit operation count limit, pass UNLIMITED_OPS for no limit
+   *  \param timeLimit time limit, pass UNLIMITED_TIME for no limit
+   *  \param tick if this LimitedIo is constructed with UnitTestTimeFixture,
+   *              this is passed to .advanceClocks(), otherwise ignored
+   */
+  StopReason
+  run(int nOpsLimit, const time::nanoseconds& timeLimit,
+      const time::nanoseconds& tick = time::milliseconds(1));
+
+  /// count an operation
+  void
+  afterOp();
+
+  /** \brief defer for specified duration
+   *
+   *  equivalent to .run(UNLIMITED_OPS, d)
+   */
+  void
+  defer(const time::nanoseconds& d)
+  {
+    this->run(UNLIMITED_OPS, d);
+  }
+
+  std::exception_ptr
+  getLastException() const
+  {
+    return m_lastException;
+  }
+
+private:
+  /** \brief an exception to stop IO operation
+   */
+  class StopException : public std::exception
+  {
+  };
+
+  void
+  afterTimeout();
+
+public:
+  static const int UNLIMITED_OPS;
+  static const time::nanoseconds UNLIMITED_TIME;
+
+private:
+  UnitTestTimeFixture* m_uttf;
+  StopReason m_reason;
+  int m_nOpsRemaining = 0;
+  scheduler::EventId m_timeout;
+  std::exception_ptr m_lastException;
+  bool m_isRunning = false;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_DAEMON_LIMITED_IO_HPP
diff --git a/tests/daemon/mgmt/face-manager-command-fixture.cpp b/tests/daemon/mgmt/face-manager-command-fixture.cpp
index 8fcb965..16e99c6 100644
--- a/tests/daemon/mgmt/face-manager-command-fixture.cpp
+++ b/tests/daemon/mgmt/face-manager-command-fixture.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,7 @@
  */
 
 #include "face-manager-command-fixture.hpp"
+#include "daemon/global.hpp"
 
 #include <ndn-cxx/net/network-monitor-stub.hpp>
 
diff --git a/tests/daemon/mgmt/manager-common-fixture.cpp b/tests/daemon/mgmt/manager-common-fixture.cpp
index ee8d543..ed4344e 100644
--- a/tests/daemon/mgmt/manager-common-fixture.cpp
+++ b/tests/daemon/mgmt/manager-common-fixture.cpp
@@ -54,7 +54,7 @@
 }
 
 ManagerCommonFixture::ManagerCommonFixture()
-  : m_face(getGlobalIoService(), m_keyChain, {true, true})
+  : m_face(g_io, m_keyChain, {true, true})
   , m_dispatcher(m_face, m_keyChain, ndn::security::SigningInfo())
   , m_responses(m_face.sentData)
 {
diff --git a/tests/daemon/mgmt/rib-manager-sl-announce.t.cpp b/tests/daemon/mgmt/rib-manager-sl-announce.t.cpp
index 452d758..5576878 100644
--- a/tests/daemon/mgmt/rib-manager-sl-announce.t.cpp
+++ b/tests/daemon/mgmt/rib-manager-sl-announce.t.cpp
@@ -163,7 +163,7 @@
 
 private:
   ndn::util::DummyClientFace m_face;
-  ndn::util::Scheduler m_scheduler;
+  Scheduler m_scheduler;
   ndn::nfd::Controller m_nfdController;
   Dispatcher m_dispatcher;
   rib::FibUpdater m_fibUpdater;
diff --git a/tests/daemon/mgmt/rib-manager.t.cpp b/tests/daemon/mgmt/rib-manager.t.cpp
index c3c5dd6..9756a36 100644
--- a/tests/daemon/mgmt/rib-manager.t.cpp
+++ b/tests/daemon/mgmt/rib-manager.t.cpp
@@ -205,7 +205,7 @@
   std::vector<Interest>& m_commands;
   ConfigurationStatus m_status;
 
-  ndn::util::Scheduler m_scheduler;
+  Scheduler m_scheduler;
   ndn::nfd::Controller m_nfdController;
   rib::Rib m_rib;
   rib::FibUpdater m_fibUpdater;
diff --git a/tests/daemon/rib-io-fixture.cpp b/tests/daemon/rib-io-fixture.cpp
new file mode 100644
index 0000000..251d6e9
--- /dev/null
+++ b/tests/daemon/rib-io-fixture.cpp
@@ -0,0 +1,148 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-io-fixture.hpp"
+#include "daemon/global.hpp"
+
+#include <boost/exception/diagnostic_information.hpp>
+
+namespace nfd {
+namespace tests {
+
+RibIoFixture::RibIoFixture()
+{
+  std::mutex m;
+  std::condition_variable cv;
+
+  g_mainIo = &getGlobalIoService();
+  setMainIoService(g_mainIo);
+
+  g_ribThread = std::thread([&] {
+    {
+      std::lock_guard<std::mutex> lock(m);
+      g_ribIo = &getGlobalIoService();
+      setRibIoService(g_ribIo);
+      BOOST_ASSERT(&g_io != g_ribIo);
+      BOOST_ASSERT(g_ribIo == &getRibIoService());
+    }
+    cv.notify_all();
+
+    try {
+      while (true) {
+        {
+          std::unique_lock<std::mutex> lock(m_ribPollMutex);
+          m_ribPollStartCv.wait(lock, [this] { return m_shouldStopRibIo || m_shouldPollRibIo; });
+          if (m_shouldStopRibIo) {
+            break;
+          }
+          BOOST_ASSERT(m_shouldPollRibIo);
+        }
+
+        if (g_ribIo->stopped()) {
+          g_ribIo->reset();
+        }
+        while (g_ribIo->poll() > 0)
+          ;
+
+        {
+          std::lock_guard<std::mutex> lock(m_ribPollMutex);
+          m_shouldPollRibIo = false;
+        }
+        m_ribPollEndCv.notify_all();
+      }
+    }
+    catch (...) {
+      BOOST_WARN_MESSAGE(false, boost::current_exception_diagnostic_information());
+      NDN_THROW_NESTED(std::runtime_error("Fatal exception in RIB thread"));
+    }
+  });
+
+  {
+    std::unique_lock<std::mutex> lock(m);
+    cv.wait(lock, [this] { return g_ribIo != nullptr; });
+  }
+}
+
+RibIoFixture::~RibIoFixture()
+{
+  {
+    std::lock_guard<std::mutex> lock(m_ribPollMutex);
+    m_shouldStopRibIo = true;
+  }
+  m_ribPollStartCv.notify_all();
+  g_ribThread.join();
+}
+
+void
+RibIoFixture::poll()
+{
+  BOOST_ASSERT(&getGlobalIoService() == &g_io);
+
+  size_t nHandlersRun = 0;
+  do {
+    {
+      std::lock_guard<std::mutex> lock(m_ribPollMutex);
+      m_shouldPollRibIo = true;
+    }
+    m_ribPollStartCv.notify_all();
+
+    if (g_io.stopped()) {
+      g_io.reset();
+    }
+
+    nHandlersRun = g_io.poll();
+
+    {
+      std::unique_lock<std::mutex> lock(m_ribPollMutex);
+      m_ribPollEndCv.wait(lock, [this] { return !m_shouldPollRibIo; });
+    }
+  } while (nHandlersRun > 0);
+}
+
+void
+RibIoTimeFixture::advanceClocks(time::nanoseconds tick, time::nanoseconds total)
+{
+  BOOST_ASSERT(tick > time::nanoseconds::zero());
+  BOOST_ASSERT(total >= time::nanoseconds::zero());
+
+  time::nanoseconds remaining = total;
+  while (remaining > time::nanoseconds::zero()) {
+    if (remaining >= tick) {
+      steadyClock->advance(tick);
+      systemClock->advance(tick);
+      remaining -= tick;
+    }
+    else {
+      steadyClock->advance(remaining);
+      systemClock->advance(remaining);
+      remaining = time::nanoseconds::zero();
+    }
+
+    poll();
+  }
+}
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/rib-io-fixture.hpp b/tests/daemon/rib-io-fixture.hpp
new file mode 100644
index 0000000..99d4387
--- /dev/null
+++ b/tests/daemon/rib-io-fixture.hpp
@@ -0,0 +1,105 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  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 NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TESTS_DAEMON_RIB_IO_FIXTURE_HPP
+#define NFD_TESTS_DAEMON_RIB_IO_FIXTURE_HPP
+
+#include "tests/test-common.hpp"
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+namespace nfd {
+namespace tests {
+
+/** \brief a base test fixture that provides both main and RIB io_service
+ */
+class RibIoFixture : public virtual BaseFixture
+{
+protected:
+  RibIoFixture();
+
+  ~RibIoFixture();
+
+protected:
+  /** \brief Poll main and RIB thread io_service to process all pending I/O events
+   *
+   * This call will execute all pending I/O events, including events that are posted
+   * inside the processing event, i.e., main and RIB thread io_service will be polled
+   * repeatedly until all pending events are processed.
+   *
+   *  \note Must be called from the main thread
+   */
+  void
+  poll();
+
+protected:
+  /** \brief pointer to global main io_service
+   */
+  boost::asio::io_service* g_mainIo = nullptr;
+
+  /** \brief pointer to global RIB io_service
+   */
+  boost::asio::io_service* g_ribIo = nullptr;
+
+  /** \brief global RIB thread
+   */
+  std::thread g_ribThread;
+
+private:
+  bool m_shouldStopRibIo = false;
+  bool m_shouldPollRibIo = false;
+  std::mutex m_ribPollMutex;
+  std::condition_variable m_ribPollStartCv;
+  std::condition_variable m_ribPollEndCv;
+};
+
+/** \brief RibIoFixture that also overrides steady clock and system clock
+ */
+class RibIoTimeFixture : public RibIoFixture, public UnitTestTimeFixture
+{
+protected:
+  using UnitTestTimeFixture::advanceClocks;
+
+  /** \brief advance steady and system clocks in the main and RIB threads
+   *
+   *  Clocks are advanced in increments of \p tick for \p total time.
+   *  The last increment might be shorter than \p tick.
+   *  After each tick, the main and RIB thread io_service is polled to process pending I/O events.
+   *
+   *  Exceptions thrown during I/O events are propagated to the caller.
+   *  Clock advancing would stop in case of an exception.
+   *
+   *  \note Must be called from the main thread
+   */
+  void
+  advanceClocks(time::nanoseconds tick, time::nanoseconds total) override;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_DAEMON_RIB_IO_FIXTURE_HPP
diff --git a/tests/daemon/rib/readvertise/nfd-rib-readvertise-destination.t.cpp b/tests/daemon/rib/readvertise/nfd-rib-readvertise-destination.t.cpp
index 4967788..d3ec057 100644
--- a/tests/daemon/rib/readvertise/nfd-rib-readvertise-destination.t.cpp
+++ b/tests/daemon/rib/readvertise/nfd-rib-readvertise-destination.t.cpp
@@ -58,7 +58,7 @@
 
 protected:
   ndn::util::DummyClientFace face;
-  ndn::util::Scheduler scheduler;
+  Scheduler scheduler;
   ndn::nfd::Controller controller;
   Rib rib;
   NfdRibReadvertiseDestination dest;
diff --git a/tests/daemon/rib/readvertise/readvertise.t.cpp b/tests/daemon/rib/readvertise/readvertise.t.cpp
index 1ff0f85..f73efbd 100644
--- a/tests/daemon/rib/readvertise/readvertise.t.cpp
+++ b/tests/daemon/rib/readvertise/readvertise.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -159,7 +159,7 @@
 
 private:
   ndn::util::DummyClientFace m_face;
-  ndn::util::Scheduler m_scheduler;
+  Scheduler m_scheduler;
   Rib m_rib;
 };
 
diff --git a/tests/daemon/rib/service.t.cpp b/tests/daemon/rib/service.t.cpp
index 14ee649..156257b 100644
--- a/tests/daemon/rib/service.t.cpp
+++ b/tests/daemon/rib/service.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,8 +24,10 @@
  */
 
 #include "rib/service.hpp"
-#include "tests/rib-io-fixture.hpp"
+#include "daemon/global.hpp"
+
 #include "tests/test-common.hpp"
+#include "tests/daemon/rib-io-fixture.hpp"
 
 namespace nfd {
 namespace rib {
diff --git a/tests/daemon/table/dead-nonce-list.t.cpp b/tests/daemon/table/dead-nonce-list.t.cpp
index 599a7e2..1df1070 100644
--- a/tests/daemon/table/dead-nonce-list.t.cpp
+++ b/tests/daemon/table/dead-nonce-list.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,7 @@
  */
 
 #include "table/dead-nonce-list.hpp"
+#include "daemon/global.hpp"
 
 #include "tests/test-common.hpp"
 
@@ -85,8 +86,7 @@
     }
 
     if (addNonceInterval > time::nanoseconds::zero()) {
-      addNonceEvent = scheduler::schedule(addNonceInterval,
-                                          bind(&PeriodicalInsertionFixture::addNonce, this));
+      addNonceEvent = getScheduler().schedule(addNonceInterval, [this] { addNonce(); });
     }
   }