| Vishwanatha Subbanna | 6dc9668 | 2017-02-06 21:47:18 +0530 | [diff] [blame] | 1 | #include <iostream> | 
 | 2 | #include <chrono> | 
 | 3 | #include <gtest/gtest.h> | 
 | 4 | #include "timer.hpp" | 
 | 5 |  | 
 | 6 | using namespace phosphor::ipmi; | 
 | 7 |  | 
 | 8 | class 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 Geissler | 8622f69 | 2017-04-02 18:19:00 -0500 | [diff] [blame] | 18 |         sd_event_source* eventSource = nullptr; | 
| Vishwanatha Subbanna | 6dc9668 | 2017-02-06 21:47:18 +0530 | [diff] [blame] | 19 |  | 
 | 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 Geissler | 8622f69 | 2017-04-02 18:19:00 -0500 | [diff] [blame] | 40 |  | 
 | 41 | class 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 Subbanna | 6dc9668 | 2017-02-06 21:47:18 +0530 | [diff] [blame] | 85 | /** @brief Makes sure that timer is expired and the | 
 | 86 |  *  callback handler gets invoked post 2 seconds | 
 | 87 |  */ | 
 | 88 | TEST_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 |  */ | 
 | 113 | TEST_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 |  */ | 
 | 144 | TEST_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 |  */ | 
 | 176 | TEST_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 Geissler | 8622f69 | 2017-04-02 18:19:00 -0500 | [diff] [blame] | 210 |  | 
 | 211 | /** @brief Makes sure that optional callback is called */ | 
 | 212 | TEST_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 |  */ | 
 | 238 | TEST_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 | } |