blob: 9ffb04ea83b640c5cd8dc6a00931d38ca97b68f0 [file] [log] [blame]
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +05301#include <iostream>
2#include <chrono>
3#include <gtest/gtest.h>
4#include "timer.hpp"
5
6using namespace phosphor::ipmi;
7
8class TimerTest : public ::testing::Test
9{
10 public:
11 // systemd event handler
12 sd_event* events;
13
14 // Need this so that events can be initialized.
15 int rc;
16
17 // Source of event
Andrew Geissler8622f692017-04-02 18:19:00 -050018 sd_event_source* eventSource = nullptr;
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053019
20 // Add a Timer Object
21 Timer timer;
22
23 // Gets called as part of each TEST_F construction
24 TimerTest()
25 : rc(sd_event_default(&events)),
26 timer(events)
27 {
28 // Check for successful creation of
29 // event handler and timer object.
30 EXPECT_GE(rc, 0);
31 }
32
33 // Gets called as part of each TEST_F destruction
34 ~TimerTest()
35 {
36 events = sd_event_unref(events);
37 }
38};
39
Andrew Geissler8622f692017-04-02 18:19:00 -050040
41class TimerTestCallBack : public ::testing::Test
42{
43 public:
44 // systemd event handler
45 sd_event* events;
46
47 // Need this so that events can be initialized.
48 int rc;
49
50 // Source of event
51 sd_event_source* eventSource = nullptr;
52
53 // Add a Timer Object
54 std::unique_ptr<Timer> timer = nullptr;
55
56 // Indicates optional call back fun was called
57 bool callBackDone = false;
58
59 void callBack()
60 {
61 callBackDone = true;
62 }
63
64 // Gets called as part of each TEST_F construction
65 TimerTestCallBack()
66 : rc(sd_event_default(&events))
67
68 {
69 // Check for successful creation of
70 // event handler and timer object.
71 EXPECT_GE(rc, 0);
72
73 std::function<void()> func(std::bind(
74 &TimerTestCallBack::callBack, this));
75 timer = std::make_unique<Timer>(events, func);
76 }
77
78 // Gets called as part of each TEST_F destruction
79 ~TimerTestCallBack()
80 {
81 events = sd_event_unref(events);
82 }
83};
84
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053085/** @brief Makes sure that timer is expired and the
86 * callback handler gets invoked post 2 seconds
87 */
88TEST_F(TimerTest, timerExpiresAfter2seconds)
89{
90 using namespace std::chrono;
91
92 auto time = duration_cast<microseconds>(seconds(2));
93 EXPECT_GE(timer.startTimer(time), 0);
94
95 // Waiting 2 seconds is enough here since we have
96 // already spent some usec now
97 int count = 0;
98 while(count < 2 && !timer.isExpired())
99 {
100 // Returns -0- on timeout and positive number on dispatch
101 auto sleepTime = duration_cast<microseconds>(seconds(1));
102 if(!sd_event_run(events, sleepTime.count()))
103 {
104 count++;
105 }
106 }
107 EXPECT_EQ(true, timer.isExpired());
108 EXPECT_EQ(1, count);
109}
110
111/** @brief Makes sure that timer is not expired
112 */
113TEST_F(TimerTest, timerNotExpiredAfter2Seconds)
114{
115 using namespace std::chrono;
116
117 auto time = duration_cast<microseconds>(seconds(2));
118 EXPECT_GE(timer.startTimer(time), 0);
119
120 // Now turn off the timer post a 1 second sleep
121 sleep(1);
122 EXPECT_GE(timer.setTimer(SD_EVENT_OFF), 0);
123
124 // Wait 2 seconds and see that timer is not expired
125 int count = 0;
126 while(count < 2)
127 {
128 // Returns -0- on timeout
129 auto sleepTime = duration_cast<microseconds>(seconds(1));
130 if(!sd_event_run(events, sleepTime.count()))
131 {
132 count++;
133 }
134 }
135 EXPECT_EQ(false, timer.isExpired());
136
137 // 2 because of one more count that happens prior to exiting
138 EXPECT_EQ(2, count);
139}
140
141/** @brief Makes sure that timer value is changed in between
142 * and that the new timer expires
143 */
144TEST_F(TimerTest, updateTimerAndExpectExpire)
145{
146 using namespace std::chrono;
147
148 auto time = duration_cast<microseconds>(seconds(2));
149 EXPECT_GE(timer.startTimer(time), 0);
150
151 // Now sleep for a second and then set the new timeout value
152 sleep(1);
153
154 // New timeout is 3 seconds from THIS point.
155 time = duration_cast<microseconds>(seconds(3));
156 EXPECT_GE(timer.startTimer(time), 0);
157
158 // Wait 3 seconds and see that timer is expired
159 int count = 0;
160 while(count < 3 && !timer.isExpired())
161 {
162 // Returns -0- on timeout
163 auto sleepTime = duration_cast<microseconds>(seconds(1));
164 if(!sd_event_run(events, sleepTime.count()))
165 {
166 count++;
167 }
168 }
169 EXPECT_EQ(true, timer.isExpired());
170 EXPECT_EQ(2, count);
171}
172
173/** @brief Makes sure that timer value is changed in between
174 * and turn off and make sure that timer does not expire
175 */
176TEST_F(TimerTest, updateTimerAndNeverExpire)
177{
178 using namespace std::chrono;
179
180 auto time = duration_cast<microseconds>(seconds(2));
181 EXPECT_GE(timer.startTimer(time), 0);
182
183 // Now sleep for a second and then set the new timeout value
184 sleep(1);
185
186 // New timeout is 2 seconds from THIS point.
187 time = duration_cast<microseconds>(seconds(2));
188 EXPECT_GE(timer.startTimer(time), 0);
189
190 // Now turn off the timer post a 1 second sleep
191 sleep(1);
192 EXPECT_GE(timer.setTimer(SD_EVENT_OFF), 0);
193
194 // Wait 2 seconds and see that timer is expired
195 int count = 0;
196 while(count < 2)
197 {
198 // Returns -0- on timeout
199 auto sleepTime = duration_cast<microseconds>(seconds(1));
200 if(!sd_event_run(events, sleepTime.count()))
201 {
202 count++;
203 }
204 }
205 EXPECT_EQ(false, timer.isExpired());
206
207 // 2 becase of one more count that happens prior to exiting
208 EXPECT_EQ(2, count);
209}
Andrew Geissler8622f692017-04-02 18:19:00 -0500210
211/** @brief Makes sure that optional callback is called */
212TEST_F(TimerTestCallBack, optionalFuncCallBackDone)
213{
214 using namespace std::chrono;
215
216 auto time = duration_cast<microseconds>(seconds(2));
217 EXPECT_GE(timer->startTimer(time), 0);
218
219 // Waiting 2 seconds is enough here since we have
220 // already spent some usec now
221 int count = 0;
222 while(count < 2 && !timer->isExpired())
223 {
224 // Returns -0- on timeout and positive number on dispatch
225 auto sleepTime = duration_cast<microseconds>(seconds(1));
226 if(!sd_event_run(events, sleepTime.count()))
227 {
228 count++;
229 }
230 }
231 EXPECT_EQ(true, timer->isExpired());
232 EXPECT_EQ(true, callBackDone);
233 EXPECT_EQ(1, count);
234}
235
236/** @brief Makes sure that timer is not expired
237 */
238TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack)
239{
240 using namespace std::chrono;
241
242 auto time = duration_cast<microseconds>(seconds(2));
243 EXPECT_GE(timer->startTimer(time), 0);
244
245 // Now turn off the timer post a 1 second sleep
246 sleep(1);
247 EXPECT_GE(timer->setTimer(SD_EVENT_OFF), 0);
248
249 // Wait 2 seconds and see that timer is not expired
250 int count = 0;
251 while(count < 2)
252 {
253 // Returns -0- on timeout
254 auto sleepTime = duration_cast<microseconds>(seconds(1));
255 if(!sd_event_run(events, sleepTime.count()))
256 {
257 count++;
258 }
259 }
260 EXPECT_EQ(false, timer->isExpired());
261 EXPECT_EQ(false, callBackDone);
262
263 // 2 because of one more count that happens prior to exiting
264 EXPECT_EQ(2, count);
265}