blob: 4f444edf4f78f8cbfcdfb611e0c65f943bcbe3e5 [file] [log] [blame]
William A. Kennington IIIaf60e632019-01-16 15:00:18 -08001#include "watchdog.hpp"
Patrick Venture8f6c5152018-09-11 17:45:33 -07002
William A. Kennington IIId1331082018-02-27 18:47:05 -08003#include <memory>
William A. Kennington IIIf505fc02018-09-12 18:30:09 -07004#include <thread>
William A. Kennington IIId1331082018-02-27 18:47:05 -08005#include <utility>
William A. Kennington III99c69de2018-03-01 10:59:22 -08006
Ofer Yehiellic35135d2019-06-14 11:30:25 -07007namespace phosphor
8{
9namespace watchdog
10{
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053011
William A. Kennington III3964f002019-01-16 15:43:43 -080012WdogTest::Quantum WdogTest::waitForWatchdog(Quantum timeLimit)
William A. Kennington III99c69de2018-03-01 10:59:22 -080013{
14 auto previousTimeRemaining = wdog->timeRemaining();
William A. Kennington III3964f002019-01-16 15:43:43 -080015 auto ret = Quantum(0);
Patrick Venture8f6c5152018-09-11 17:45:33 -070016 while (ret < timeLimit && previousTimeRemaining >= wdog->timeRemaining() &&
William A. Kennington III99c69de2018-03-01 10:59:22 -080017 wdog->timerEnabled())
18 {
19 previousTimeRemaining = wdog->timeRemaining();
20
William A. Kennington III3964f002019-01-16 15:43:43 -080021 constexpr auto sleepTime = Quantum(1);
William A. Kennington IIIf505fc02018-09-12 18:30:09 -070022 if (event.run(sleepTime) == 0)
William A. Kennington III99c69de2018-03-01 10:59:22 -080023 {
24 ret += sleepTime;
25 }
26 }
27
28 return ret;
29}
30
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053031/** @brief Make sure that watchdog is started and not enabled */
32TEST_F(WdogTest, createWdogAndDontEnable)
33{
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080034 EXPECT_FALSE(wdog->enabled());
35 EXPECT_EQ(0, wdog->timeRemaining());
36 EXPECT_FALSE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -080037 EXPECT_FALSE(wdog->timerEnabled());
William A. Kennington III25c1b202018-03-01 11:00:19 -080038
39 // We should be able to configure persistent properties
40 // while disabled
41 auto newAction = Watchdog::Action::PowerOff;
42 EXPECT_EQ(newAction, wdog->expireAction(newAction));
43 auto newIntervalMs = milliseconds(defaultInterval * 2).count();
44 EXPECT_EQ(newIntervalMs, wdog->interval(newIntervalMs));
45
46 EXPECT_EQ(newAction, wdog->expireAction());
47 EXPECT_EQ(newIntervalMs, wdog->interval());
48
49 // We won't be able to configure timeRemaining
50 EXPECT_EQ(0, wdog->timeRemaining(1000));
51 EXPECT_EQ(0, wdog->timeRemaining());
52
53 // Timer should not have become enabled
54 EXPECT_FALSE(wdog->enabled());
55 EXPECT_EQ(0, wdog->timeRemaining());
56 EXPECT_FALSE(wdog->timerExpired());
57 EXPECT_FALSE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053058}
59
60/** @brief Make sure that watchdog is started and enabled */
61TEST_F(WdogTest, createWdogAndEnable)
62{
63 // Enable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080064 EXPECT_TRUE(wdog->enabled(true));
65 EXPECT_FALSE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -080066 EXPECT_TRUE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053067
68 // Get the configured interval
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080069 auto remaining = milliseconds(wdog->timeRemaining());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053070
71 // Its possible that we are off by few msecs depending on
72 // how we get scheduled. So checking a range here.
William A. Kennington III3964f002019-01-16 15:43:43 -080073 EXPECT_TRUE((remaining >= defaultInterval - Quantum(1)) &&
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053074 (remaining <= defaultInterval));
75
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080076 EXPECT_FALSE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -080077 EXPECT_TRUE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053078}
79
80/** @brief Make sure that watchdog is started and enabled.
81 * Later, disable watchdog
82 */
83TEST_F(WdogTest, createWdogAndEnableThenDisable)
84{
85 // Enable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080086 EXPECT_TRUE(wdog->enabled(true));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053087
88 // Disable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -080089 EXPECT_FALSE(wdog->enabled(false));
90 EXPECT_FALSE(wdog->enabled());
91 EXPECT_EQ(0, wdog->timeRemaining());
William A. Kennington III0650a3f2018-03-01 10:53:25 -080092 EXPECT_FALSE(wdog->timerExpired());
93 EXPECT_FALSE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053094}
95
96/** @brief Make sure that watchdog is started and enabled.
William A. Kennington III3964f002019-01-16 15:43:43 -080097 * Wait for 5 quantums and make sure that the remaining
98 * time shows 5 fewer quantums.
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053099 */
William A. Kennington III3964f002019-01-16 15:43:43 -0800100TEST_F(WdogTest, enableWdogAndWait5Quantums)
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530101{
102 // Enable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800103 EXPECT_TRUE(wdog->enabled(true));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530104
William A. Kennington III3964f002019-01-16 15:43:43 -0800105 // Sleep for 5 quantums
106 auto sleepTime = Quantum(2);
107 ASSERT_LT(sleepTime, defaultInterval);
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530108 std::this_thread::sleep_for(sleepTime);
109
William A. Kennington III3964f002019-01-16 15:43:43 -0800110 // Get the remaining time again and expectation is that we get fewer
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800111 auto remaining = milliseconds(wdog->timeRemaining());
William A. Kennington III8cd38392018-03-01 11:07:36 -0800112 auto expected = defaultInterval - sleepTime;
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530113
114 // Its possible that we are off by few msecs depending on
115 // how we get scheduled. So checking a range here.
William A. Kennington III3964f002019-01-16 15:43:43 -0800116 EXPECT_TRUE((remaining >= expected - Quantum(1)) &&
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530117 (remaining <= expected));
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800118 EXPECT_FALSE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800119 EXPECT_TRUE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530120}
121
122/** @brief Make sure that watchdog is started and enabled.
William A. Kennington III3964f002019-01-16 15:43:43 -0800123 * Wait 1 quantum and then reset the timer to 5 quantums
124 * and then expect the watchdog to expire in 5 quantums
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530125 */
William A. Kennington III3964f002019-01-16 15:43:43 -0800126TEST_F(WdogTest, enableWdogAndResetTo5Quantums)
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530127{
128 // Enable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800129 EXPECT_TRUE(wdog->enabled(true));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530130
131 // Sleep for 1 second
William A. Kennington III3964f002019-01-16 15:43:43 -0800132 std::this_thread::sleep_for(Quantum(1));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530133
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700134 // Timer should still be running unexpired
135 EXPECT_FALSE(wdog->timerExpired());
136 EXPECT_TRUE(wdog->timerEnabled());
137
William A. Kennington III3964f002019-01-16 15:43:43 -0800138 // Next timer will expire in 5 quantums from now.
139 auto expireTime = Quantum(5);
William A. Kennington III8cd38392018-03-01 11:07:36 -0800140 auto expireTimeMs = milliseconds(expireTime).count();
141 EXPECT_EQ(expireTimeMs, wdog->timeRemaining(expireTimeMs));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530142
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530143 // Waiting for expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800144 EXPECT_EQ(expireTime - Quantum(1), waitForWatchdog(expireTime));
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800145 EXPECT_TRUE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800146 EXPECT_FALSE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530147}
148
Gunnar Millsbfe5cb82017-10-25 20:48:50 -0500149/** @brief Make sure the Interval can be updated directly.
Patrick Venture96816342017-08-17 12:32:22 -0700150 */
151TEST_F(WdogTest, verifyIntervalUpdateReceived)
152{
William A. Kennington III3964f002019-01-16 15:43:43 -0800153 auto expireTime = Quantum(5);
William A. Kennington III8cd38392018-03-01 11:07:36 -0800154 auto expireTimeMs = milliseconds(expireTime).count();
155 EXPECT_EQ(expireTimeMs, wdog->interval(expireTimeMs));
Patrick Venture96816342017-08-17 12:32:22 -0700156
157 // Expect an update in the Interval
William A. Kennington III8cd38392018-03-01 11:07:36 -0800158 EXPECT_EQ(expireTimeMs, wdog->interval());
Patrick Venture96816342017-08-17 12:32:22 -0700159}
160
William A. Kennington IIId4cbc5a2018-09-24 14:23:05 -0700161/** @brief Make sure the Interval can be updated while the timer is running.
162 */
163TEST_F(WdogTest, verifyIntervalUpdateRunning)
164{
165 const auto oldInterval = milliseconds(wdog->interval());
166 const auto newInterval = 5s;
167
168 EXPECT_TRUE(wdog->enabled(true));
169 auto remaining = milliseconds(wdog->timeRemaining());
170 EXPECT_GE(oldInterval, remaining);
William A. Kennington III3964f002019-01-16 15:43:43 -0800171 EXPECT_LE(oldInterval - Quantum(1), remaining);
William A. Kennington IIId4cbc5a2018-09-24 14:23:05 -0700172 EXPECT_EQ(newInterval,
173 milliseconds(wdog->interval(milliseconds(newInterval).count())));
174
175 // Expect only the interval to update
176 remaining = milliseconds(wdog->timeRemaining());
177 EXPECT_GE(oldInterval, remaining);
William A. Kennington III3964f002019-01-16 15:43:43 -0800178 EXPECT_LE(oldInterval - Quantum(1), remaining);
William A. Kennington IIId4cbc5a2018-09-24 14:23:05 -0700179 EXPECT_EQ(newInterval, milliseconds(wdog->interval()));
180
181 // Expect reset to use the new interval
182 wdog->resetTimeRemaining(false);
183 remaining = milliseconds(wdog->timeRemaining());
184 EXPECT_GE(newInterval, remaining);
William A. Kennington III3964f002019-01-16 15:43:43 -0800185 EXPECT_LE(newInterval - Quantum(1), remaining);
William A. Kennington IIId4cbc5a2018-09-24 14:23:05 -0700186}
187
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530188/** @brief Make sure that watchdog is started and enabled.
William A. Kennington III3964f002019-01-16 15:43:43 -0800189 * Wait default interval quantums and make sure that wdog has died
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530190 */
191TEST_F(WdogTest, enableWdogAndWaitTillEnd)
192{
193 // Enable and then verify
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800194 EXPECT_TRUE(wdog->enabled(true));
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530195
196 // Waiting default expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800197 EXPECT_EQ(defaultInterval - Quantum(1), waitForWatchdog(defaultInterval));
William A. Kennington III99c69de2018-03-01 10:59:22 -0800198
William A. Kennington III825f4982018-02-27 19:10:56 -0800199 EXPECT_FALSE(wdog->enabled());
William A. Kennington IIIf0fe2d62018-02-28 15:20:16 -0800200 EXPECT_EQ(0, wdog->timeRemaining());
201 EXPECT_TRUE(wdog->timerExpired());
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800202 EXPECT_FALSE(wdog->timerEnabled());
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +0530203}
William A. Kennington IIId1331082018-02-27 18:47:05 -0800204
205/** @brief Make sure the watchdog is started and enabled with a fallback
206 * Wait through the initial trip and ensure the fallback is observed
207 * Make sure that fallback runs to completion and ensure the watchdog
208 * is disabled
209 */
210TEST_F(WdogTest, enableWdogWithFallbackTillEnd)
211{
William A. Kennington III3964f002019-01-16 15:43:43 -0800212 auto primaryInterval = Quantum(5);
William A. Kennington IIId1331082018-02-27 18:47:05 -0800213 auto primaryIntervalMs = milliseconds(primaryInterval).count();
214 auto fallbackInterval = primaryInterval * 2;
215 auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
216
217 // We need to make a wdog with the right fallback options
218 // The interval is set to be noticeably different from the default
219 // so we can always tell the difference
William A. Kennington III8cf5f642019-01-16 16:58:14 -0800220 Watchdog::Fallback fallback;
221 fallback.action = Watchdog::Action::PowerOff;
222 fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
223 fallback.always = false;
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700224 wdog.reset();
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700225 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
William A. Kennington III3bb2f402018-09-13 00:35:47 -0700226 Watchdog::ActionTargetMap(),
Patrick Venture8f6c5152018-09-11 17:45:33 -0700227 std::move(fallback));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800228 EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
229 EXPECT_FALSE(wdog->enabled());
230 EXPECT_EQ(0, wdog->timeRemaining());
231
232 // Enable and then verify
233 EXPECT_TRUE(wdog->enabled(true));
234
235 // Waiting default expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800236 EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800237
238 // We should now have entered the fallback once the primary expires
239 EXPECT_FALSE(wdog->enabled());
240 auto remaining = milliseconds(wdog->timeRemaining());
241 EXPECT_GE(fallbackInterval, remaining);
242 EXPECT_LT(primaryInterval, remaining);
243 EXPECT_FALSE(wdog->timerExpired());
244 EXPECT_TRUE(wdog->timerEnabled());
245
246 // We should still be ticking in fallback when setting action or interval
William A. Kennington III3964f002019-01-16 15:43:43 -0800247 auto newInterval = primaryInterval - Quantum(1);
William A. Kennington IIId1331082018-02-27 18:47:05 -0800248 auto newIntervalMs = milliseconds(newInterval).count();
249 EXPECT_EQ(newInterval, milliseconds(wdog->interval(newIntervalMs)));
250 EXPECT_EQ(Watchdog::Action::None,
Patrick Venture8f6c5152018-09-11 17:45:33 -0700251 wdog->expireAction(Watchdog::Action::None));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800252
253 EXPECT_FALSE(wdog->enabled());
254 EXPECT_GE(remaining, milliseconds(wdog->timeRemaining()));
255 EXPECT_LT(primaryInterval, milliseconds(wdog->timeRemaining()));
256 EXPECT_FALSE(wdog->timerExpired());
257 EXPECT_TRUE(wdog->timerEnabled());
258
259 // Test that setting the timeRemaining always resets the timer to the
260 // fallback interval
261 EXPECT_EQ(fallback.interval, wdog->timeRemaining(primaryInterval.count()));
262 EXPECT_FALSE(wdog->enabled());
263
264 remaining = milliseconds(wdog->timeRemaining());
265 EXPECT_GE(fallbackInterval, remaining);
William A. Kennington III3964f002019-01-16 15:43:43 -0800266 EXPECT_LE(fallbackInterval - Quantum(1), remaining);
William A. Kennington IIId1331082018-02-27 18:47:05 -0800267 EXPECT_FALSE(wdog->timerExpired());
268 EXPECT_TRUE(wdog->timerEnabled());
269
270 // Waiting fallback expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800271 EXPECT_EQ(fallbackInterval - Quantum(1), waitForWatchdog(fallbackInterval));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800272
273 // We should now have disabled the watchdog after the fallback expires
274 EXPECT_FALSE(wdog->enabled());
275 EXPECT_EQ(0, wdog->timeRemaining());
276 EXPECT_TRUE(wdog->timerExpired());
277 EXPECT_FALSE(wdog->timerEnabled());
278
279 // Make sure enabling the watchdog again works
280 EXPECT_TRUE(wdog->enabled(true));
281
282 // We should have re-entered the primary
283 EXPECT_TRUE(wdog->enabled());
284 EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
285 EXPECT_FALSE(wdog->timerExpired());
286 EXPECT_TRUE(wdog->timerEnabled());
287}
288
289/** @brief Make sure the watchdog is started and enabled with a fallback
290 * Wait through the initial trip and ensure the fallback is observed
291 * Make sure that we can re-enable the watchdog during fallback
292 */
293TEST_F(WdogTest, enableWdogWithFallbackReEnable)
294{
William A. Kennington III3964f002019-01-16 15:43:43 -0800295 auto primaryInterval = Quantum(5);
William A. Kennington IIId1331082018-02-27 18:47:05 -0800296 auto primaryIntervalMs = milliseconds(primaryInterval).count();
297 auto fallbackInterval = primaryInterval * 2;
298 auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
299
300 // We need to make a wdog with the right fallback options
301 // The interval is set to be noticeably different from the default
302 // so we can always tell the difference
William A. Kennington III8cf5f642019-01-16 16:58:14 -0800303 Watchdog::Fallback fallback;
304 fallback.action = Watchdog::Action::PowerOff;
305 fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
306 fallback.always = false;
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700307 wdog.reset();
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700308 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
William A. Kennington III3bb2f402018-09-13 00:35:47 -0700309 Watchdog::ActionTargetMap(),
Patrick Venture8f6c5152018-09-11 17:45:33 -0700310 std::move(fallback));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800311 EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
312 EXPECT_FALSE(wdog->enabled());
313 EXPECT_EQ(0, wdog->timeRemaining());
314 EXPECT_FALSE(wdog->timerExpired());
315 EXPECT_FALSE(wdog->timerEnabled());
316
317 // Enable and then verify
318 EXPECT_TRUE(wdog->enabled(true));
319
320 // Waiting default expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800321 EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
William A. Kennington IIId1331082018-02-27 18:47:05 -0800322
323 // We should now have entered the fallback once the primary expires
324 EXPECT_FALSE(wdog->enabled());
325 auto remaining = milliseconds(wdog->timeRemaining());
326 EXPECT_GE(fallbackInterval, remaining);
327 EXPECT_LT(primaryInterval, remaining);
328 EXPECT_FALSE(wdog->timerExpired());
329 EXPECT_TRUE(wdog->timerEnabled());
330
331 EXPECT_TRUE(wdog->enabled(true));
332
333 // We should have re-entered the primary
334 EXPECT_TRUE(wdog->enabled());
335 EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
336 EXPECT_FALSE(wdog->timerExpired());
337 EXPECT_TRUE(wdog->timerEnabled());
338}
William A. Kennington III22352192018-02-27 18:51:44 -0800339
Kun Yi50cc9562019-12-04 11:46:59 -0800340/** @brief Make sure the watchdog is started and enabled with a fallback
341 * Wait through the initial trip and ensure the fallback is observed
342 * Make sure that changing the primary interval and calling reset timer
343 * will enable the primary watchdog with primary interval.
344 */
345TEST_F(WdogTest, enableWdogWithFallbackResetTimerEnable)
346{
347 auto primaryInterval = Quantum(5);
348 auto primaryIntervalMs = milliseconds(primaryInterval).count();
349 auto fallbackInterval = primaryInterval * 2;
350 auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
351 auto newInterval = fallbackInterval * 2;
352 auto newIntervalMs = milliseconds(newInterval).count();
353
354 // We need to make a wdog with the right fallback options
355 // The interval is set to be noticeably different from the default
356 // so we can always tell the difference
357 Watchdog::Fallback fallback;
358 fallback.action = Watchdog::Action::PowerOff;
359 fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
360 fallback.always = false;
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700361 wdog.reset();
Kun Yi50cc9562019-12-04 11:46:59 -0800362 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
363 Watchdog::ActionTargetMap(),
364 std::move(fallback));
365 EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
366 EXPECT_FALSE(wdog->enabled());
367 EXPECT_EQ(0, wdog->timeRemaining());
368 EXPECT_FALSE(wdog->timerExpired());
369 EXPECT_FALSE(wdog->timerEnabled());
370
371 // Enable and then verify
372 EXPECT_TRUE(wdog->enabled(true));
373
374 // Waiting default expiration
375 EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
376
377 // We should now have entered the fallback once the primary expires
378 EXPECT_FALSE(wdog->enabled());
379 auto remaining = milliseconds(wdog->timeRemaining());
380 EXPECT_GE(fallbackInterval, remaining);
381 EXPECT_LT(primaryInterval, remaining);
382 EXPECT_FALSE(wdog->timerExpired());
383 EXPECT_TRUE(wdog->timerEnabled());
384
385 // Setting the interval should take effect once resetTimer re-enables wdog
386 EXPECT_EQ(newIntervalMs, wdog->interval(newIntervalMs));
387 wdog->resetTimeRemaining(true);
388
389 // We should have re-entered the primary
390 EXPECT_TRUE(wdog->enabled());
391 remaining = milliseconds(wdog->timeRemaining());
392 EXPECT_GE(newInterval, remaining);
393 EXPECT_LE(newInterval - Quantum(1), remaining);
394 EXPECT_FALSE(wdog->timerExpired());
395 EXPECT_TRUE(wdog->timerEnabled());
396}
397
William A. Kennington III22352192018-02-27 18:51:44 -0800398/** @brief Make sure the watchdog is started and with a fallback without
399 * sending an enable
400 * Then enable the watchdog
401 * Wait through the initial trip and ensure the fallback is observed
402 * Make sure that fallback runs to completion and ensure the watchdog
403 * is in the fallback state again
404 */
405TEST_F(WdogTest, enableWdogWithFallbackAlways)
406{
William A. Kennington III3964f002019-01-16 15:43:43 -0800407 auto primaryInterval = Quantum(5);
William A. Kennington III22352192018-02-27 18:51:44 -0800408 auto primaryIntervalMs = milliseconds(primaryInterval).count();
409 auto fallbackInterval = primaryInterval * 2;
410 auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
411
412 // We need to make a wdog with the right fallback options
413 // The interval is set to be noticeably different from the default
414 // so we can always tell the difference
William A. Kennington III8cf5f642019-01-16 16:58:14 -0800415 Watchdog::Fallback fallback;
416 fallback.action = Watchdog::Action::PowerOff;
417 fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
418 fallback.always = true;
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700419 wdog.reset();
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700420 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700421 Watchdog::ActionTargetMap(), fallback,
422 milliseconds(TEST_MIN_INTERVAL).count());
423
424 // Make sure defualt interval is biggger than min interval
425 EXPECT_LT(milliseconds((TEST_MIN_INTERVAL).count()),
426 milliseconds(wdog->interval()));
427
William A. Kennington III22352192018-02-27 18:51:44 -0800428 EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
429 EXPECT_FALSE(wdog->enabled());
430 auto remaining = milliseconds(wdog->timeRemaining());
431 EXPECT_GE(fallbackInterval, remaining);
432 EXPECT_LT(primaryInterval, remaining);
433 EXPECT_FALSE(wdog->timerExpired());
434 EXPECT_TRUE(wdog->timerEnabled());
435
436 // Enable and then verify
437 EXPECT_TRUE(wdog->enabled(true));
438 EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
439
440 // Waiting default expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800441 EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
William A. Kennington III22352192018-02-27 18:51:44 -0800442
443 // We should now have entered the fallback once the primary expires
444 EXPECT_FALSE(wdog->enabled());
445 remaining = milliseconds(wdog->timeRemaining());
446 EXPECT_GE(fallbackInterval, remaining);
447 EXPECT_LT(primaryInterval, remaining);
448 EXPECT_FALSE(wdog->timerExpired());
449 EXPECT_TRUE(wdog->timerEnabled());
450
451 // Waiting fallback expiration
William A. Kennington III3964f002019-01-16 15:43:43 -0800452 EXPECT_EQ(fallbackInterval - Quantum(1), waitForWatchdog(fallbackInterval));
William A. Kennington III22352192018-02-27 18:51:44 -0800453
454 // We should now enter the fallback again
455 EXPECT_FALSE(wdog->enabled());
456 remaining = milliseconds(wdog->timeRemaining());
457 EXPECT_GE(fallbackInterval, remaining);
458 EXPECT_LT(primaryInterval, remaining);
459 EXPECT_FALSE(wdog->timerExpired());
460 EXPECT_TRUE(wdog->timerEnabled());
461}
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700462
463/** @brief Test minimal interval
464 * The minimal interval was set 2 seconds
465 * Test that when setting interval to 1s , it is still returning 2s
466 */
467TEST_F(WdogTest, verifyMinIntervalSetting)
468{
469 auto newInterval = Quantum(1);
470 auto newIntervalMs = milliseconds(newInterval).count();
471 auto minIntervalMs = milliseconds(TEST_MIN_INTERVAL).count();
472
473 // Check first that the current interval is greater than minInterval
474 EXPECT_LT(minIntervalMs, wdog->interval());
475 // Check that the interval was not set to smaller value than minInterval
476 EXPECT_EQ(minIntervalMs, wdog->interval(newIntervalMs));
477 // Check that the interval was not set to smaller value than minInterval
478 EXPECT_EQ(minIntervalMs, wdog->interval());
479}
480
481/** @brief Test minimal interval
482 * Initiate default Watchdog in order to get the default
483 * interval.
484 * Initiate watchdog with minInterval greater than default
485 * interval, and make sure the default interval was set to the
486 * minInterval.
487 */
488TEST_F(WdogTest, verifyConstructorMinIntervalSetting)
489{
490 // Initiate default Watchdog and get the default interval value.
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700491 wdog.reset();
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700492 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event);
Kun Yie8e11c62019-12-04 16:35:47 -0800493 auto defaultIntervalMs = wdog->interval();
494 auto defaultInterval = milliseconds(defaultIntervalMs);
495 auto minInterval = defaultInterval + Quantum(30);
496 auto minIntervalMs = milliseconds(minInterval).count();
497
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700498 // We initiate a new Watchdog with min interval greater than the default
499 // intrval
William A. Kennington III1859eeb2021-04-20 16:08:57 -0700500 wdog.reset();
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700501 wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
502 Watchdog::ActionTargetMap(), std::nullopt,
Kun Yie8e11c62019-12-04 16:35:47 -0800503 minIntervalMs);
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700504 // Check that the interval was set to the minInterval
Kun Yie8e11c62019-12-04 16:35:47 -0800505 EXPECT_EQ(minIntervalMs, wdog->interval());
506
507 // Enable and then verify
508 EXPECT_TRUE(wdog->enabled(true));
509 EXPECT_FALSE(wdog->timerExpired());
510 EXPECT_TRUE(wdog->timerEnabled());
511
512 // Set remaining time shorter than minInterval will actually set it to
513 // minInterval
514 auto remaining = milliseconds(wdog->timeRemaining(defaultIntervalMs));
515
516 // Its possible that we are off by few msecs depending on
517 // how we get scheduled. So checking a range here.
518 EXPECT_TRUE((remaining >= minInterval - Quantum(1)) &&
519 (remaining <= minInterval));
520
521 EXPECT_FALSE(wdog->timerExpired());
522 EXPECT_TRUE(wdog->timerEnabled());
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700523}
524
525} // namespace watchdog
526} // namespace phosphor