blob: 0dd99ae139b5337bd2e62f59074c72f725c86821 [file] [log] [blame]
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +05301#include "timer.hpp"
2
Patrick Venture0b02be92018-08-31 11:55:55 -07003#include <chrono>
4#include <iostream>
5
6#include <gtest/gtest.h>
7
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +05308using namespace phosphor::ipmi;
9
10class TimerTest : public ::testing::Test
11{
Patrick Venture0b02be92018-08-31 11:55:55 -070012 public:
13 // systemd event handler
14 sd_event* events;
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053015
Patrick Venture0b02be92018-08-31 11:55:55 -070016 // Need this so that events can be initialized.
17 int rc;
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053018
Patrick Venture0b02be92018-08-31 11:55:55 -070019 // Source of event
20 sd_event_source* eventSource = nullptr;
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053021
Patrick Venture0b02be92018-08-31 11:55:55 -070022 // Add a Timer Object
23 Timer timer;
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053024
Patrick Venture0b02be92018-08-31 11:55:55 -070025 // Gets called as part of each TEST_F construction
26 TimerTest() : rc(sd_event_default(&events)), timer(events)
27 {
28 // Check for successful creation of
29 // event handler and timer object.
30 EXPECT_GE(rc, 0);
31 }
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053032
Patrick Venture0b02be92018-08-31 11:55:55 -070033 // Gets called as part of each TEST_F destruction
34 ~TimerTest()
35 {
36 events = sd_event_unref(events);
37 }
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053038};
39
Andrew Geissler8622f692017-04-02 18:19:00 -050040class TimerTestCallBack : public ::testing::Test
41{
Patrick Venture0b02be92018-08-31 11:55:55 -070042 public:
43 // systemd event handler
44 sd_event* events;
Andrew Geissler8622f692017-04-02 18:19:00 -050045
Patrick Venture0b02be92018-08-31 11:55:55 -070046 // Need this so that events can be initialized.
47 int rc;
Andrew Geissler8622f692017-04-02 18:19:00 -050048
Patrick Venture0b02be92018-08-31 11:55:55 -070049 // Source of event
50 sd_event_source* eventSource = nullptr;
Andrew Geissler8622f692017-04-02 18:19:00 -050051
Patrick Venture0b02be92018-08-31 11:55:55 -070052 // Add a Timer Object
53 std::unique_ptr<Timer> timer = nullptr;
Andrew Geissler8622f692017-04-02 18:19:00 -050054
Patrick Venture0b02be92018-08-31 11:55:55 -070055 // Indicates optional call back fun was called
56 bool callBackDone = false;
Andrew Geissler8622f692017-04-02 18:19:00 -050057
Patrick Venture0b02be92018-08-31 11:55:55 -070058 void callBack()
59 {
60 callBackDone = true;
61 }
Andrew Geissler8622f692017-04-02 18:19:00 -050062
Patrick Venture0b02be92018-08-31 11:55:55 -070063 // Gets called as part of each TEST_F construction
64 TimerTestCallBack() : rc(sd_event_default(&events))
Andrew Geissler8622f692017-04-02 18:19:00 -050065
Patrick Venture0b02be92018-08-31 11:55:55 -070066 {
67 // Check for successful creation of
68 // event handler and timer object.
69 EXPECT_GE(rc, 0);
Andrew Geissler8622f692017-04-02 18:19:00 -050070
Patrick Venture0b02be92018-08-31 11:55:55 -070071 std::function<void()> func(
72 std::bind(&TimerTestCallBack::callBack, this));
73 timer = std::make_unique<Timer>(events, func);
74 }
Andrew Geissler8622f692017-04-02 18:19:00 -050075
Patrick Venture0b02be92018-08-31 11:55:55 -070076 // Gets called as part of each TEST_F destruction
77 ~TimerTestCallBack()
78 {
79 events = sd_event_unref(events);
80 }
Andrew Geissler8622f692017-04-02 18:19:00 -050081};
82
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053083/** @brief Makes sure that timer is expired and the
84 * callback handler gets invoked post 2 seconds
85 */
86TEST_F(TimerTest, timerExpiresAfter2seconds)
87{
88 using namespace std::chrono;
89
90 auto time = duration_cast<microseconds>(seconds(2));
91 EXPECT_GE(timer.startTimer(time), 0);
92
93 // Waiting 2 seconds is enough here since we have
94 // already spent some usec now
95 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -070096 while (count < 2 && !timer.isExpired())
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +053097 {
98 // Returns -0- on timeout and positive number on dispatch
99 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700100 if (!sd_event_run(events, sleepTime.count()))
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530101 {
102 count++;
103 }
104 }
105 EXPECT_EQ(true, timer.isExpired());
106 EXPECT_EQ(1, count);
107}
108
109/** @brief Makes sure that timer is not expired
110 */
111TEST_F(TimerTest, timerNotExpiredAfter2Seconds)
112{
113 using namespace std::chrono;
114
115 auto time = duration_cast<microseconds>(seconds(2));
116 EXPECT_GE(timer.startTimer(time), 0);
117
118 // Now turn off the timer post a 1 second sleep
119 sleep(1);
120 EXPECT_GE(timer.setTimer(SD_EVENT_OFF), 0);
121
122 // Wait 2 seconds and see that timer is not expired
123 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -0700124 while (count < 2)
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530125 {
126 // Returns -0- on timeout
127 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700128 if (!sd_event_run(events, sleepTime.count()))
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530129 {
130 count++;
131 }
132 }
133 EXPECT_EQ(false, timer.isExpired());
134
135 // 2 because of one more count that happens prior to exiting
136 EXPECT_EQ(2, count);
137}
138
139/** @brief Makes sure that timer value is changed in between
140 * and that the new timer expires
141 */
142TEST_F(TimerTest, updateTimerAndExpectExpire)
143{
144 using namespace std::chrono;
145
146 auto time = duration_cast<microseconds>(seconds(2));
147 EXPECT_GE(timer.startTimer(time), 0);
148
149 // Now sleep for a second and then set the new timeout value
150 sleep(1);
151
152 // New timeout is 3 seconds from THIS point.
153 time = duration_cast<microseconds>(seconds(3));
154 EXPECT_GE(timer.startTimer(time), 0);
155
156 // Wait 3 seconds and see that timer is expired
157 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -0700158 while (count < 3 && !timer.isExpired())
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530159 {
160 // Returns -0- on timeout
161 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700162 if (!sd_event_run(events, sleepTime.count()))
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530163 {
164 count++;
165 }
166 }
167 EXPECT_EQ(true, timer.isExpired());
168 EXPECT_EQ(2, count);
169}
170
171/** @brief Makes sure that timer value is changed in between
172 * and turn off and make sure that timer does not expire
173 */
174TEST_F(TimerTest, updateTimerAndNeverExpire)
175{
176 using namespace std::chrono;
177
178 auto time = duration_cast<microseconds>(seconds(2));
179 EXPECT_GE(timer.startTimer(time), 0);
180
181 // Now sleep for a second and then set the new timeout value
182 sleep(1);
183
184 // New timeout is 2 seconds from THIS point.
185 time = duration_cast<microseconds>(seconds(2));
186 EXPECT_GE(timer.startTimer(time), 0);
187
188 // Now turn off the timer post a 1 second sleep
189 sleep(1);
190 EXPECT_GE(timer.setTimer(SD_EVENT_OFF), 0);
191
192 // Wait 2 seconds and see that timer is expired
193 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -0700194 while (count < 2)
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530195 {
196 // Returns -0- on timeout
197 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700198 if (!sd_event_run(events, sleepTime.count()))
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530199 {
200 count++;
201 }
202 }
203 EXPECT_EQ(false, timer.isExpired());
204
Gunnar Mills8991dd62017-10-25 17:11:29 -0500205 // 2 because of one more count that happens prior to exiting
Vishwanatha Subbanna6dc96682017-02-06 21:47:18 +0530206 EXPECT_EQ(2, count);
207}
Andrew Geissler8622f692017-04-02 18:19:00 -0500208
209/** @brief Makes sure that optional callback is called */
210TEST_F(TimerTestCallBack, optionalFuncCallBackDone)
211{
212 using namespace std::chrono;
213
214 auto time = duration_cast<microseconds>(seconds(2));
215 EXPECT_GE(timer->startTimer(time), 0);
216
217 // Waiting 2 seconds is enough here since we have
218 // already spent some usec now
219 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -0700220 while (count < 2 && !timer->isExpired())
Andrew Geissler8622f692017-04-02 18:19:00 -0500221 {
222 // Returns -0- on timeout and positive number on dispatch
223 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700224 if (!sd_event_run(events, sleepTime.count()))
Andrew Geissler8622f692017-04-02 18:19:00 -0500225 {
226 count++;
227 }
228 }
229 EXPECT_EQ(true, timer->isExpired());
230 EXPECT_EQ(true, callBackDone);
231 EXPECT_EQ(1, count);
232}
233
234/** @brief Makes sure that timer is not expired
235 */
236TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack)
237{
238 using namespace std::chrono;
239
240 auto time = duration_cast<microseconds>(seconds(2));
241 EXPECT_GE(timer->startTimer(time), 0);
242
243 // Now turn off the timer post a 1 second sleep
244 sleep(1);
245 EXPECT_GE(timer->setTimer(SD_EVENT_OFF), 0);
246
247 // Wait 2 seconds and see that timer is not expired
248 int count = 0;
Patrick Venture0b02be92018-08-31 11:55:55 -0700249 while (count < 2)
Andrew Geissler8622f692017-04-02 18:19:00 -0500250 {
251 // Returns -0- on timeout
252 auto sleepTime = duration_cast<microseconds>(seconds(1));
Patrick Venture0b02be92018-08-31 11:55:55 -0700253 if (!sd_event_run(events, sleepTime.count()))
Andrew Geissler8622f692017-04-02 18:19:00 -0500254 {
255 count++;
256 }
257 }
258 EXPECT_EQ(false, timer->isExpired());
259 EXPECT_EQ(false, callBackDone);
260
261 // 2 because of one more count that happens prior to exiting
262 EXPECT_EQ(2, count);
263}