blob: 0d70abf4397e94b4d6f129d9d3b19b3040f63c08 [file] [log] [blame]
Alexander Afanasyevabe952a2013-01-17 17:06:32 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 */
21
22#include "scheduler.h"
23#include "simple-interval-generator.h"
24#include "one-time-task.h"
25#include "periodic-task.h"
26#include "random-interval-generator.h"
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080027
28#include <boost/test/unit_test.hpp>
Zhenkai Zhu3566f2f2013-01-25 23:47:59 -080029#include <boost/make_shared.hpp>
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080030#include <map>
31#include <unistd.h>
32
33using namespace boost;
34using namespace std;
35
36BOOST_AUTO_TEST_SUITE(SchedulerTests)
37
38map<string, int> table;
39
40void func(string str)
41{
42 map<string, int>::iterator it = table.find(str);
43 if (it == table.end())
44 {
45 table.insert(make_pair(str, 1));
46 }
47 else
48 {
49 int count = it->second;
50 count++;
51 table.erase(it);
52 table.insert(make_pair(str, count));
53 }
54}
55
56bool
57matcher(const TaskPtr &task)
58{
59 return task->tag() == "period" || task->tag() == "world";
60}
61
62BOOST_AUTO_TEST_CASE(SchedulerTest)
63{
64 SchedulerPtr scheduler(new Scheduler());
65 IntervalGeneratorPtr generator(new SimpleIntervalGenerator(0.2));
66
67 string tag1 = "hello";
68 string tag2 = "world";
69 string tag3 = "period";
70
Zhenkai Zhu66dc5a92013-01-08 21:41:15 -080071 TaskPtr task1(new OneTimeTask(boost::bind(func, tag1), tag1, scheduler, 0.5));
72 TaskPtr task2(new OneTimeTask(boost::bind(func, tag2), tag2, scheduler, 0.5));
73 TaskPtr task3(new PeriodicTask(boost::bind(func, tag3), tag3, scheduler, generator));
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080074
75 scheduler->start();
Zhenkai Zhu66dc5a92013-01-08 21:41:15 -080076 scheduler->addTask(task1);
77 scheduler->addTask(task2);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080078 scheduler->addTask(task3);
79 BOOST_CHECK_EQUAL(scheduler->size(), 3);
80 usleep(600000);
81 BOOST_CHECK_EQUAL(scheduler->size(), 1);
Zhenkai Zhu66dc5a92013-01-08 21:41:15 -080082 scheduler->addTask(task1);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080083 BOOST_CHECK_EQUAL(scheduler->size(), 2);
84 usleep(600000);
Zhenkai Zhu66dc5a92013-01-08 21:41:15 -080085 scheduler->addTask(task1);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080086 BOOST_CHECK_EQUAL(scheduler->size(), 2);
87 usleep(400000);
88 scheduler->deleteTask(task1->tag());
89 BOOST_CHECK_EQUAL(scheduler->size(), 1);
90 usleep(200000);
91
Zhenkai Zhu66dc5a92013-01-08 21:41:15 -080092 scheduler->addTask(task1);
93 scheduler->addTask(task2);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080094 BOOST_CHECK_EQUAL(scheduler->size(), 3);
95 usleep(100000);
96 scheduler->deleteTask(bind(matcher, _1));
97 BOOST_CHECK_EQUAL(scheduler->size(), 1);
Zhenkai Zhu06b8e952013-01-15 12:21:15 -080098 usleep(1000000);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -080099
Zhenkai Zhud2ca3922013-01-18 17:58:48 -0800100 BOOST_CHECK_EQUAL(scheduler->size(), 0);
101 scheduler->addTask(task1);
102 usleep(400000);
103 BOOST_CHECK_EQUAL(scheduler->size(), 1);
104 scheduler->rescheduleTask(task1);
105 usleep(400000);
106 BOOST_CHECK_EQUAL(scheduler->size(), 1);
107 usleep(110000);
108 BOOST_CHECK_EQUAL(scheduler->size(), 0);
109
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800110
Zhenkai Zhu06b8e952013-01-15 12:21:15 -0800111 int hello = 0, world = 0, period = 0;
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800112
113 map<string, int>::iterator it;
114 it = table.find(tag1);
115 if (it != table.end())
116 {
117 hello = it->second;
118 }
119 it = table.find(tag2);
120 if (it != table.end())
121 {
122 world = it->second;
123 }
124 it = table.find(tag3);
125 if (it != table.end())
126 {
127 period = it->second;
128 }
129
Zhenkai Zhud2ca3922013-01-18 17:58:48 -0800130 // added five times, canceled once before invoking callback
131 BOOST_CHECK_EQUAL(hello, 4);
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800132 // added two times, canceled once by matcher before invoking callback
133 BOOST_CHECK_EQUAL(world, 1);
134 // invoked every 0.2 seconds before deleted by matcher
135 BOOST_CHECK_EQUAL(period, static_cast<int>((0.6 + 0.6 + 0.4 + 0.2 + 0.1) / 0.2));
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800136
Zhenkai Zhuf8e81e02013-01-15 16:02:47 -0800137 scheduler->shutdown();
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800138}
139
Zhenkai Zhu3566f2f2013-01-25 23:47:59 -0800140void reschedule();
141SchedulerPtr schd0(new Scheduler());
142int resCount;
143TaskPtr task0(new PeriodicTask(boost::bind(reschedule), "testtest", schd0, boost::make_shared<SimpleIntervalGenerator>(0.5)));
144void reschedule()
145{
146 schd0->rescheduleTask(task0);
147 resCount++;
148}
149
150BOOST_AUTO_TEST_CASE(RescheduleTest)
151{
152 resCount = 0;
153 schd0->start();
154 schd0->addTask(task0);
155 usleep(5100000);
156 BOOST_CHECK_EQUAL(resCount, 10);
157 schd0->shutdown();
158}
159
Zhenkai Zhubc2f6282013-01-08 16:40:58 -0800160BOOST_AUTO_TEST_CASE(GeneratorTest)
161{
162 double interval = 10;
163 double percent = 0.5;
164 int times = 10000;
165 IntervalGeneratorPtr generator(new RandomIntervalGenerator(interval, percent));
166 double sum = 0.0;
167 double min = 2 * interval;
168 double max = -1;
169 for (int i = 0; i < times; i++)
170 {
171 double next = generator->nextInterval();
172 sum += next;
173 if (next > max)
174 {
175 max = next;
176 }
177 if (next < min)
178 {
179 min = next;
180 }
181 }
182
183 BOOST_CHECK( abs(1.0 - (sum / static_cast<double>(times)) / interval) < 0.05);
184 BOOST_CHECK( min > interval * (1 - percent / 2.0));
185 BOOST_CHECK( max < interval * (1 + percent / 2.0));
186 BOOST_CHECK( abs(1.0 - ((max - min) / interval) / percent) < 0.05);
187
188}
189
190BOOST_AUTO_TEST_SUITE_END()