blob: fab5b7669cf59ec50150af6efc17eefafb5c8303 [file] [log] [blame]
Jeff Thompsonfa306642013-06-17 15:06:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 * Zhenkai Zhu
6 *
7 * BSD license, See the LICENSE file for more information
8 *
9 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
10 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
11 */
12
13#include "scheduler/scheduler-all.h"
14
15#include <boost/test/unit_test.hpp>
16#include <boost/make_shared.hpp>
17#include <map>
18#include <unistd.h>
19
20using namespace boost;
21using namespace std;
22
23BOOST_AUTO_TEST_SUITE(SchedulerTests)
24
25map<string, int> table;
26
27void func(string str)
28{
29 map<string, int>::iterator it = table.find(str);
30 if (it == table.end())
31 {
32 table.insert(make_pair(str, 1));
33 }
34 else
35 {
36 int count = it->second;
37 count++;
38 table.erase(it);
39 table.insert(make_pair(str, count));
40 }
41}
42
43bool
44matcher(const TaskPtr &task)
45{
46 return task->tag() == "period" || task->tag() == "world";
47}
48
49BOOST_AUTO_TEST_CASE(SchedulerTest)
50{
51 SchedulerPtr scheduler(new Scheduler());
52 IntervalGeneratorPtr generator(new SimpleIntervalGenerator(0.2));
53
54 string tag1 = "hello";
55 string tag2 = "world";
56 string tag3 = "period";
57
58 TaskPtr task1(new OneTimeTask(boost::bind(func, tag1), tag1, scheduler, 0.5));
59 TaskPtr task2(new OneTimeTask(boost::bind(func, tag2), tag2, scheduler, 0.5));
60 TaskPtr task3(new PeriodicTask(boost::bind(func, tag3), tag3, scheduler, generator));
61
62 scheduler->start();
63 scheduler->addTask(task1);
64 scheduler->addTask(task2);
65 scheduler->addTask(task3);
66 BOOST_CHECK_EQUAL(scheduler->size(), 3);
67 usleep(600000);
68 BOOST_CHECK_EQUAL(scheduler->size(), 1);
69 scheduler->addTask(task1);
70 BOOST_CHECK_EQUAL(scheduler->size(), 2);
71 usleep(600000);
72 scheduler->addTask(task1);
73 BOOST_CHECK_EQUAL(scheduler->size(), 2);
74 usleep(400000);
75 scheduler->deleteTask(task1->tag());
76 BOOST_CHECK_EQUAL(scheduler->size(), 1);
77 usleep(200000);
78
79 scheduler->addTask(task1);
80 scheduler->addTask(task2);
81 BOOST_CHECK_EQUAL(scheduler->size(), 3);
82 usleep(100000);
83 scheduler->deleteTask(bind(matcher, _1));
84 BOOST_CHECK_EQUAL(scheduler->size(), 1);
85 usleep(1000000);
86
87 BOOST_CHECK_EQUAL(scheduler->size(), 0);
88 scheduler->addTask(task1);
89 usleep(400000);
90 BOOST_CHECK_EQUAL(scheduler->size(), 1);
91 scheduler->rescheduleTask(task1);
92 usleep(400000);
93 BOOST_CHECK_EQUAL(scheduler->size(), 1);
94 usleep(110000);
95 BOOST_CHECK_EQUAL(scheduler->size(), 0);
96
97
98 int hello = 0, world = 0, period = 0;
99
100 map<string, int>::iterator it;
101 it = table.find(tag1);
102 if (it != table.end())
103 {
104 hello = it->second;
105 }
106 it = table.find(tag2);
107 if (it != table.end())
108 {
109 world = it->second;
110 }
111 it = table.find(tag3);
112 if (it != table.end())
113 {
114 period = it->second;
115 }
116
117 // added five times, canceled once before invoking callback
118 BOOST_CHECK_EQUAL(hello, 4);
119 // added two times, canceled once by matcher before invoking callback
120 BOOST_CHECK_EQUAL(world, 1);
121 // invoked every 0.2 seconds before deleted by matcher
122 BOOST_CHECK_EQUAL(period, static_cast<int>((0.6 + 0.6 + 0.4 + 0.2 + 0.1) / 0.2));
123
124 scheduler->shutdown();
125}
126
127void reschedule();
128SchedulerPtr schd0(new Scheduler());
129int resCount;
130TaskPtr task0(new PeriodicTask(boost::bind(reschedule), "testtest", schd0, boost::make_shared<SimpleIntervalGenerator>(0.5)));
131void reschedule()
132{
133 schd0->rescheduleTask(task0);
134 resCount++;
135}
136
137BOOST_AUTO_TEST_CASE(RescheduleTest)
138{
139 resCount = 0;
140 schd0->start();
141 schd0->addTask(task0);
142 usleep(5100000);
143 BOOST_CHECK_EQUAL(resCount, 10);
144 schd0->shutdown();
145}
146
147BOOST_AUTO_TEST_CASE(GeneratorTest)
148{
149 double interval = 10;
150 double percent = 0.5;
151 int times = 10000;
152 IntervalGeneratorPtr generator(new RandomIntervalGenerator(interval, percent));
153 double sum = 0.0;
154 double min = 2 * interval;
155 double max = -1;
156 for (int i = 0; i < times; i++)
157 {
158 double next = generator->nextInterval();
159 sum += next;
160 if (next > max)
161 {
162 max = next;
163 }
164 if (next < min)
165 {
166 min = next;
167 }
168 }
169
170 BOOST_CHECK( abs(1.0 - (sum / static_cast<double>(times)) / interval) < 0.05);
171 BOOST_CHECK( min > interval * (1 - percent / 2.0));
172 BOOST_CHECK( max < interval * (1 + percent / 2.0));
173 BOOST_CHECK( abs(1.0 - ((max - min) / interval) / percent) < 0.05);
174
175}
176
177BOOST_AUTO_TEST_SUITE_END()