blob: 3b8feb0098f3b2bb59ae6f4f40a1ab4efbbd5a03 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevf6468892014-01-29 01:04:14 -08002/**
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevf6468892014-01-29 01:04:14 -080020 */
21
22#include "util/scheduler.hpp"
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080023#include "util/scheduler-scoped-event-id.hpp"
Alexander Afanasyevf6468892014-01-29 01:04:14 -080024
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070025#include "boost-test.hpp"
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080026#include "../unit-test-time-fixture.hpp"
Alexander Afanasyevf6468892014-01-29 01:04:14 -080027
28namespace ndn {
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080029namespace util {
30namespace scheduler {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080031namespace tests {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080032
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080033BOOST_FIXTURE_TEST_SUITE(UtilTestScheduler, ::ndn::tests::UnitTestTimeFixture)
Alexander Afanasyevf6468892014-01-29 01:04:14 -080034
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080035BOOST_AUTO_TEST_CASE(Events)
Alexander Afanasyevf6468892014-01-29 01:04:14 -080036{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080037 size_t count1 = 0;
38 size_t count2 = 0;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080039
40 Scheduler scheduler(io);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080041 scheduler.scheduleEvent(time::milliseconds(500), [&] {
42 ++count1;
43 BOOST_CHECK_EQUAL(count2, 1);
44 });
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070045
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080046 EventId i = scheduler.scheduleEvent(time::seconds(1), [&] {
47 BOOST_ERROR("This event should not have been fired");
48 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080049 scheduler.cancelEvent(i);
50
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080051 scheduler.scheduleEvent(time::milliseconds(250), [&] {
52 BOOST_CHECK_EQUAL(count1, 0);
53 ++count2;
54 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080055
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080056 i = scheduler.scheduleEvent(time::milliseconds(50), [&] {
57 BOOST_ERROR("This event should not have been fired");
58 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080059 scheduler.cancelEvent(i);
60
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080061 advanceClocks(time::milliseconds(1), 1000);
Alexander Afanasyevf6468892014-01-29 01:04:14 -080062 BOOST_CHECK_EQUAL(count1, 1);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080063 BOOST_CHECK_EQUAL(count2, 1);
Alexander Afanasyevf6468892014-01-29 01:04:14 -080064}
65
Yingdi Yuf2a82092014-02-03 16:49:15 -080066BOOST_AUTO_TEST_CASE(CancelEmptyEvent)
67{
Yingdi Yuf2a82092014-02-03 16:49:15 -080068 Scheduler scheduler(io);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070069
Yingdi Yuf2a82092014-02-03 16:49:15 -080070 EventId i;
71 scheduler.cancelEvent(i);
72}
73
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080074BOOST_AUTO_TEST_CASE(SelfCancel)
Yingdi Yuf2a82092014-02-03 16:49:15 -080075{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080076 Scheduler scheduler(io);
Yingdi Yuf2a82092014-02-03 16:49:15 -080077
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080078 EventId selfEventId;
79 selfEventId = scheduler.scheduleEvent(time::milliseconds(100), [&] {
80 scheduler.cancelEvent(selfEventId);
81 });
Yingdi Yuf2a82092014-02-03 16:49:15 -080082
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080083 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(100), 10));
Yingdi Yuf2a82092014-02-03 16:49:15 -080084}
85
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080086class SelfRescheduleFixture : public ::ndn::tests::UnitTestTimeFixture
Yingdi Yuf2a82092014-02-03 16:49:15 -080087{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080088public:
Yingdi Yuf2a82092014-02-03 16:49:15 -080089 SelfRescheduleFixture()
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080090 : scheduler(io)
91 , count(0)
Yingdi Yuf2a82092014-02-03 16:49:15 -080092 {
93 }
94
95 void
96 reschedule()
97 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080098 EventId eventId = scheduler.scheduleEvent(time::milliseconds(100),
99 bind(&SelfRescheduleFixture::reschedule, this));
100 scheduler.cancelEvent(selfEventId);
101 selfEventId = eventId;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800102
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800103 if (count < 5)
104 count++;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800105 else
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800106 scheduler.cancelEvent(selfEventId);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800107 }
108
109 void
110 reschedule2()
111 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800112 scheduler.cancelEvent(selfEventId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700113
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800114 if (count < 5) {
115 selfEventId = scheduler.scheduleEvent(time::milliseconds(100),
116 bind(&SelfRescheduleFixture::reschedule2, this));
117 count++;
118 }
Yingdi Yuf2a82092014-02-03 16:49:15 -0800119 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700120
Yingdi Yuf2a82092014-02-03 16:49:15 -0800121 void
122 reschedule3()
123 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800124 scheduler.cancelEvent(selfEventId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800126 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
127 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
128 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
129 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
130 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
131 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
Yingdi Yuf2a82092014-02-03 16:49:15 -0800132 }
133
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800134 Scheduler scheduler;
135 EventId selfEventId;
136 size_t count;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800137};
138
139BOOST_FIXTURE_TEST_CASE(Reschedule, SelfRescheduleFixture)
140{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800141 selfEventId = scheduler.scheduleEvent(time::seconds(0),
142 bind(&SelfRescheduleFixture::reschedule, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800143
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800144 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800145
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800146 BOOST_CHECK_EQUAL(count, 5);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800147}
148
149BOOST_FIXTURE_TEST_CASE(Reschedule2, SelfRescheduleFixture)
150{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800151 selfEventId = scheduler.scheduleEvent(time::seconds(0),
152 bind(&SelfRescheduleFixture::reschedule2, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800153
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800154 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800155
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800156 BOOST_CHECK_EQUAL(count, 5);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800157}
158
159BOOST_FIXTURE_TEST_CASE(Reschedule3, SelfRescheduleFixture)
160{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800161 selfEventId = scheduler.scheduleEvent(time::seconds(0),
162 bind(&SelfRescheduleFixture::reschedule3, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800163
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800164 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800165
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800166 BOOST_CHECK_EQUAL(count, 6);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800167}
168
169
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800170struct CancelAllFixture : public ::ndn::tests::UnitTestTimeFixture
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700171{
172 CancelAllFixture()
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800173 : scheduler(io)
174 , count(0)
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700175 {
176 }
177
178 void
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700179 event()
180 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800181 ++count;
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700182
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800183 scheduler.scheduleEvent(time::seconds(1), [&] { event(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700184 }
185
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800186 Scheduler scheduler;
187 uint32_t count;
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700188};
189
190
191BOOST_FIXTURE_TEST_CASE(CancelAll, CancelAllFixture)
192{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800193 scheduler.scheduleEvent(time::milliseconds(500), [&] { scheduler.cancelAllEvents(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700194
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800195 scheduler.scheduleEvent(time::seconds(1), [&] { event(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700196
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800197 scheduler.scheduleEvent(time::seconds(3), [] {
198 BOOST_ERROR("This event should have been cancelled" );
199 });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700200
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800201 advanceClocks(time::milliseconds(100), 100);
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700202
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800203 BOOST_CHECK_EQUAL(count, 0);
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700204}
205
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800206class ScopedEventFixture : public ::ndn::tests::UnitTestTimeFixture
207{
208public:
209 ScopedEventFixture()
210 : scheduler(io)
211 {
212 }
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700213
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800214public:
215 Scheduler scheduler;
216};
217
218BOOST_FIXTURE_TEST_SUITE(ScopedEvents, ScopedEventFixture)
219
220BOOST_AUTO_TEST_CASE(ScopedEventIdDestruct)
221{
222 int hit = 0;
223 {
224 ScopedEventId se(scheduler);
225 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
226 } // se goes out of scope
227 this->advanceClocks(time::milliseconds(1), 15);
228 BOOST_CHECK_EQUAL(hit, 0);
229}
230
231BOOST_AUTO_TEST_CASE(ScopedEventIdAssign)
232{
233 int hit1 = 0, hit2 = 0;
234 ScopedEventId se1(scheduler);
235 se1 = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit1; });
236 se1 = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit2; });
237 this->advanceClocks(time::milliseconds(1), 15);
238 BOOST_CHECK_EQUAL(hit1, 0);
239 BOOST_CHECK_EQUAL(hit2, 1);
240}
241
242BOOST_AUTO_TEST_CASE(ScopedEventIdRelease)
243{
244 int hit = 0;
245 {
246 ScopedEventId se(scheduler);
247 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
248 se.release();
249 } // se goes out of scope
250 this->advanceClocks(time::milliseconds(1), 15);
251 BOOST_CHECK_EQUAL(hit, 1);
252}
253
254BOOST_AUTO_TEST_CASE(ScopedEventIdMove)
255{
256 int hit = 0;
257 unique_ptr<scheduler::ScopedEventId> se2;
258 {
259 ScopedEventId se(scheduler);
260 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
261 se2.reset(new ScopedEventId(std::move(se)));
262 } // se goes out of scope
263 this->advanceClocks(time::milliseconds(1), 15);
264 BOOST_CHECK_EQUAL(hit, 1);
265}
266
267BOOST_AUTO_TEST_SUITE_END() // ScopedEventId
268
269BOOST_AUTO_TEST_SUITE_END() // UtilTestScheduler
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800270
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800271} // namespace tests
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800272} // namespace scheduler
273} // namespace util
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800274} // namespace ndn