blob: 8e22f1eec82b9919e7d4bc31f3770b8454c42d3e [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
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080033using namespace ndn::tests;
34
35BOOST_FIXTURE_TEST_SUITE(UtilScheduler, UnitTestTimeFixture)
Alexander Afanasyevf6468892014-01-29 01:04:14 -080036
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080037BOOST_AUTO_TEST_CASE(Events)
Alexander Afanasyevf6468892014-01-29 01:04:14 -080038{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080039 size_t count1 = 0;
40 size_t count2 = 0;
Alexander Afanasyevf6468892014-01-29 01:04:14 -080041
42 Scheduler scheduler(io);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080043 scheduler.scheduleEvent(time::milliseconds(500), [&] {
44 ++count1;
45 BOOST_CHECK_EQUAL(count2, 1);
46 });
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080048 EventId i = scheduler.scheduleEvent(time::seconds(1), [&] {
49 BOOST_ERROR("This event should not have been fired");
50 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080051 scheduler.cancelEvent(i);
52
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080053 scheduler.scheduleEvent(time::milliseconds(250), [&] {
54 BOOST_CHECK_EQUAL(count1, 0);
55 ++count2;
56 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080057
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080058 i = scheduler.scheduleEvent(time::milliseconds(50), [&] {
59 BOOST_ERROR("This event should not have been fired");
60 });
Alexander Afanasyevf6468892014-01-29 01:04:14 -080061 scheduler.cancelEvent(i);
62
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080063 advanceClocks(time::milliseconds(1), 1000);
Alexander Afanasyevf6468892014-01-29 01:04:14 -080064 BOOST_CHECK_EQUAL(count1, 1);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080065 BOOST_CHECK_EQUAL(count2, 1);
Alexander Afanasyevf6468892014-01-29 01:04:14 -080066}
67
Yingdi Yuf2a82092014-02-03 16:49:15 -080068BOOST_AUTO_TEST_CASE(CancelEmptyEvent)
69{
Yingdi Yuf2a82092014-02-03 16:49:15 -080070 Scheduler scheduler(io);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070071
Yingdi Yuf2a82092014-02-03 16:49:15 -080072 EventId i;
73 scheduler.cancelEvent(i);
74}
75
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080076BOOST_AUTO_TEST_CASE(SelfCancel)
Yingdi Yuf2a82092014-02-03 16:49:15 -080077{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080078 Scheduler scheduler(io);
Yingdi Yuf2a82092014-02-03 16:49:15 -080079
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080080 EventId selfEventId;
81 selfEventId = scheduler.scheduleEvent(time::milliseconds(100), [&] {
82 scheduler.cancelEvent(selfEventId);
83 });
Yingdi Yuf2a82092014-02-03 16:49:15 -080084
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080085 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(100), 10));
Yingdi Yuf2a82092014-02-03 16:49:15 -080086}
87
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080088class SelfRescheduleFixture : public UnitTestTimeFixture
Yingdi Yuf2a82092014-02-03 16:49:15 -080089{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080090public:
Yingdi Yuf2a82092014-02-03 16:49:15 -080091 SelfRescheduleFixture()
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080092 : scheduler(io)
93 , count(0)
Yingdi Yuf2a82092014-02-03 16:49:15 -080094 {
95 }
96
97 void
98 reschedule()
99 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800100 EventId eventId = scheduler.scheduleEvent(time::milliseconds(100),
101 bind(&SelfRescheduleFixture::reschedule, this));
102 scheduler.cancelEvent(selfEventId);
103 selfEventId = eventId;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800104
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800105 if (count < 5)
106 count++;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800107 else
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800108 scheduler.cancelEvent(selfEventId);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800109 }
110
111 void
112 reschedule2()
113 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800114 scheduler.cancelEvent(selfEventId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700115
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800116 if (count < 5) {
117 selfEventId = scheduler.scheduleEvent(time::milliseconds(100),
118 bind(&SelfRescheduleFixture::reschedule2, this));
119 count++;
120 }
Yingdi Yuf2a82092014-02-03 16:49:15 -0800121 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700122
Yingdi Yuf2a82092014-02-03 16:49:15 -0800123 void
124 reschedule3()
125 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800126 scheduler.cancelEvent(selfEventId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700127
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800128 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; });
132 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
133 scheduler.scheduleEvent(time::milliseconds(100), [&] { ++count; });
Yingdi Yuf2a82092014-02-03 16:49:15 -0800134 }
135
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800136 Scheduler scheduler;
137 EventId selfEventId;
138 size_t count;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800139};
140
141BOOST_FIXTURE_TEST_CASE(Reschedule, SelfRescheduleFixture)
142{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800143 selfEventId = scheduler.scheduleEvent(time::seconds(0),
144 bind(&SelfRescheduleFixture::reschedule, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800145
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800146 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800147
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800148 BOOST_CHECK_EQUAL(count, 5);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800149}
150
151BOOST_FIXTURE_TEST_CASE(Reschedule2, SelfRescheduleFixture)
152{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800153 selfEventId = scheduler.scheduleEvent(time::seconds(0),
154 bind(&SelfRescheduleFixture::reschedule2, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800155
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800156 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800157
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800158 BOOST_CHECK_EQUAL(count, 5);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800159}
160
161BOOST_FIXTURE_TEST_CASE(Reschedule3, SelfRescheduleFixture)
162{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800163 selfEventId = scheduler.scheduleEvent(time::seconds(0),
164 bind(&SelfRescheduleFixture::reschedule3, this));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800165
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800166 BOOST_REQUIRE_NO_THROW(advanceClocks(time::milliseconds(10), 1000));
Yingdi Yuf2a82092014-02-03 16:49:15 -0800167
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800168 BOOST_CHECK_EQUAL(count, 6);
Yingdi Yuf2a82092014-02-03 16:49:15 -0800169}
170
171
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800172struct CancelAllFixture : public ::ndn::tests::UnitTestTimeFixture
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700173{
174 CancelAllFixture()
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800175 : scheduler(io)
176 , count(0)
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700177 {
178 }
179
180 void
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700181 event()
182 {
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800183 ++count;
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700184
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800185 scheduler.scheduleEvent(time::seconds(1), [&] { event(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700186 }
187
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800188 Scheduler scheduler;
189 uint32_t count;
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700190};
191
192
193BOOST_FIXTURE_TEST_CASE(CancelAll, CancelAllFixture)
194{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800195 scheduler.scheduleEvent(time::milliseconds(500), [&] { scheduler.cancelAllEvents(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700196
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800197 scheduler.scheduleEvent(time::seconds(1), [&] { event(); });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700198
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800199 scheduler.scheduleEvent(time::seconds(3), [] {
200 BOOST_ERROR("This event should have been cancelled" );
201 });
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700202
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800203 advanceClocks(time::milliseconds(100), 100);
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700204
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800205 BOOST_CHECK_EQUAL(count, 0);
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700206}
207
Spyridon Mastorakis429634f2015-02-19 17:35:33 -0800208class ScopedEventFixture : public UnitTestTimeFixture
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800209{
210public:
211 ScopedEventFixture()
212 : scheduler(io)
213 {
214 }
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700215
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800216public:
217 Scheduler scheduler;
218};
219
220BOOST_FIXTURE_TEST_SUITE(ScopedEvents, ScopedEventFixture)
221
222BOOST_AUTO_TEST_CASE(ScopedEventIdDestruct)
223{
224 int hit = 0;
225 {
226 ScopedEventId se(scheduler);
227 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
228 } // se goes out of scope
229 this->advanceClocks(time::milliseconds(1), 15);
230 BOOST_CHECK_EQUAL(hit, 0);
231}
232
233BOOST_AUTO_TEST_CASE(ScopedEventIdAssign)
234{
235 int hit1 = 0, hit2 = 0;
236 ScopedEventId se1(scheduler);
237 se1 = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit1; });
238 se1 = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit2; });
239 this->advanceClocks(time::milliseconds(1), 15);
240 BOOST_CHECK_EQUAL(hit1, 0);
241 BOOST_CHECK_EQUAL(hit2, 1);
242}
243
244BOOST_AUTO_TEST_CASE(ScopedEventIdRelease)
245{
246 int hit = 0;
247 {
248 ScopedEventId se(scheduler);
249 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
250 se.release();
251 } // se goes out of scope
252 this->advanceClocks(time::milliseconds(1), 15);
253 BOOST_CHECK_EQUAL(hit, 1);
254}
255
256BOOST_AUTO_TEST_CASE(ScopedEventIdMove)
257{
258 int hit = 0;
259 unique_ptr<scheduler::ScopedEventId> se2;
260 {
261 ScopedEventId se(scheduler);
262 se = scheduler.scheduleEvent(time::milliseconds(10), [&] { ++hit; });
263 se2.reset(new ScopedEventId(std::move(se)));
264 } // se goes out of scope
265 this->advanceClocks(time::milliseconds(1), 15);
266 BOOST_CHECK_EQUAL(hit, 1);
267}
268
269BOOST_AUTO_TEST_SUITE_END() // ScopedEventId
270
271BOOST_AUTO_TEST_SUITE_END() // UtilTestScheduler
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800272
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800273} // namespace tests
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800274} // namespace scheduler
275} // namespace util
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800276} // namespace ndn