1 #include "watchdog.hpp"
2 
3 #include <chrono>
4 #include <memory>
5 #include <sdbusplus/bus.hpp>
6 #include <sdeventplus/event.hpp>
7 #include <thread>
8 #include <utility>
9 
10 #include <gtest/gtest.h>
11 
12 namespace phosphor
13 {
14 namespace watchdog
15 {
16 
17 using namespace std::chrono;
18 using namespace std::chrono_literals;
19 
20 constexpr auto TEST_MIN_INTERVAL = duration<uint64_t, std::deci>(2);
21 
22 // Test Watchdog functionality
23 class WdogTest : public ::testing::Test
24 {
25   public:
26     // The unit time used to measure the timer
27     // This should be large enough to accomodate drift
28     using Quantum = duration<uint64_t, std::deci>;
29 
30     // Gets called as part of each TEST_F construction
31     WdogTest() :
32         event(sdeventplus::Event::get_default()),
33         bus(sdbusplus::bus::new_default()),
34         wdog(std::make_unique<Watchdog>(
35             bus, TEST_PATH, event, Watchdog::ActionTargetMap(), std::nullopt,
36             milliseconds(TEST_MIN_INTERVAL).count())),
37 
38         defaultInterval(Quantum(3))
39 
40     {
41         wdog->interval(milliseconds(defaultInterval).count());
42         // Initially the watchdog would be disabled
43         EXPECT_FALSE(wdog->enabled());
44     }
45 
46     // sdevent Event handle
47     sdeventplus::Event event;
48 
49     // sdbusplus handle
50     sdbusplus::bus_t bus;
51 
52     // Watchdog object
53     std::unique_ptr<Watchdog> wdog;
54 
55     // This is the default interval as given in Interface definition
56     Quantum defaultInterval;
57 
58   protected:
59     // Dummy name for object path
60     // This is just to satisfy the constructor. Does not have
61     // a need to check if the objects paths have been created.
62     static constexpr auto TEST_PATH = "/test/path";
63 
64     // Returns how long it took for the current watchdog timer to be
65     // disabled or have its timeRemaining reset.
66     Quantum waitForWatchdog(Quantum timeLimit)
67     {
68         auto previousTimeRemaining = wdog->timeRemaining();
69         auto ret = Quantum(0);
70         while (ret < timeLimit &&
71                previousTimeRemaining >= wdog->timeRemaining() &&
72                wdog->timerEnabled())
73         {
74             previousTimeRemaining = wdog->timeRemaining();
75 
76             constexpr auto sleepTime = Quantum(1);
77             if (event.run(sleepTime) == 0)
78             {
79                 ret += sleepTime;
80             }
81         }
82 
83         return ret;
84     }
85 };
86 
87 /** @brief Make sure that watchdog is started and not enabled */
88 TEST_F(WdogTest, createWdogAndDontEnable)
89 {
90     EXPECT_FALSE(wdog->enabled());
91     EXPECT_EQ(0, wdog->timeRemaining());
92     EXPECT_FALSE(wdog->timerExpired());
93     EXPECT_FALSE(wdog->timerEnabled());
94 
95     // We should be able to configure persistent properties
96     // while disabled
97     auto newAction = Watchdog::Action::PowerOff;
98     EXPECT_EQ(newAction, wdog->expireAction(newAction));
99     auto newIntervalMs = milliseconds(defaultInterval * 2).count();
100     EXPECT_EQ(newIntervalMs, wdog->interval(newIntervalMs));
101 
102     EXPECT_EQ(newAction, wdog->expireAction());
103     EXPECT_EQ(newIntervalMs, wdog->interval());
104 
105     // We won't be able to configure timeRemaining
106     EXPECT_EQ(0, wdog->timeRemaining(1000));
107     EXPECT_EQ(0, wdog->timeRemaining());
108 
109     // Timer should not have become enabled
110     EXPECT_FALSE(wdog->enabled());
111     EXPECT_EQ(0, wdog->timeRemaining());
112     EXPECT_FALSE(wdog->timerExpired());
113     EXPECT_FALSE(wdog->timerEnabled());
114 }
115 
116 /** @brief Make sure that watchdog is started and enabled */
117 TEST_F(WdogTest, createWdogAndEnable)
118 {
119     // Enable and then verify
120     EXPECT_TRUE(wdog->enabled(true));
121     EXPECT_FALSE(wdog->timerExpired());
122     EXPECT_TRUE(wdog->timerEnabled());
123 
124     // Get the configured interval
125     auto remaining = milliseconds(wdog->timeRemaining());
126 
127     // Its possible that we are off by few msecs depending on
128     // how we get scheduled. So checking a range here.
129     EXPECT_TRUE((remaining >= defaultInterval - Quantum(1)) &&
130                 (remaining <= defaultInterval));
131 
132     EXPECT_FALSE(wdog->timerExpired());
133     EXPECT_TRUE(wdog->timerEnabled());
134 }
135 
136 /** @brief Make sure that watchdog is started and enabled.
137  *         Later, disable watchdog
138  */
139 TEST_F(WdogTest, createWdogAndEnableThenDisable)
140 {
141     // Enable and then verify
142     EXPECT_TRUE(wdog->enabled(true));
143 
144     // Disable and then verify
145     EXPECT_FALSE(wdog->enabled(false));
146     EXPECT_FALSE(wdog->enabled());
147     EXPECT_EQ(0, wdog->timeRemaining());
148     EXPECT_FALSE(wdog->timerExpired());
149     EXPECT_FALSE(wdog->timerEnabled());
150 }
151 
152 /** @brief Make sure that watchdog is started and enabled.
153  *         Wait for 5 quantums and make sure that the remaining
154  *         time shows 5 fewer quantums.
155  */
156 TEST_F(WdogTest, enableWdogAndWait5Quantums)
157 {
158     // Enable and then verify
159     EXPECT_TRUE(wdog->enabled(true));
160 
161     // Sleep for 5 quantums
162     auto sleepTime = Quantum(2);
163     ASSERT_LT(sleepTime, defaultInterval);
164     std::this_thread::sleep_for(sleepTime);
165 
166     // Get the remaining time again and expectation is that we get fewer
167     auto remaining = milliseconds(wdog->timeRemaining());
168     auto expected = defaultInterval - sleepTime;
169 
170     // Its possible that we are off by few msecs depending on
171     // how we get scheduled. So checking a range here.
172     EXPECT_TRUE((remaining >= expected - Quantum(1)) &&
173                 (remaining <= expected));
174     EXPECT_FALSE(wdog->timerExpired());
175     EXPECT_TRUE(wdog->timerEnabled());
176 }
177 
178 /** @brief Make sure that watchdog is started and enabled.
179  *         Wait 1 quantum and then reset the timer to 5 quantums
180  *         and then expect the watchdog to expire in 5 quantums
181  */
182 TEST_F(WdogTest, enableWdogAndResetTo5Quantums)
183 {
184     // Enable and then verify
185     EXPECT_TRUE(wdog->enabled(true));
186 
187     // Sleep for 1 second
188     std::this_thread::sleep_for(Quantum(1));
189 
190     // Timer should still be running unexpired
191     EXPECT_FALSE(wdog->timerExpired());
192     EXPECT_TRUE(wdog->timerEnabled());
193 
194     // Next timer will expire in 5 quantums from now.
195     auto expireTime = Quantum(5);
196     auto expireTimeMs = milliseconds(expireTime).count();
197     EXPECT_EQ(expireTimeMs, wdog->timeRemaining(expireTimeMs));
198 
199     // Waiting for expiration
200     EXPECT_EQ(expireTime - Quantum(1), waitForWatchdog(expireTime));
201     EXPECT_TRUE(wdog->timerExpired());
202     EXPECT_FALSE(wdog->timerEnabled());
203 }
204 
205 /** @brief Make sure the Interval can be updated directly.
206  */
207 TEST_F(WdogTest, verifyIntervalUpdateReceived)
208 {
209     auto expireTime = Quantum(5);
210     auto expireTimeMs = milliseconds(expireTime).count();
211     EXPECT_EQ(expireTimeMs, wdog->interval(expireTimeMs));
212 
213     // Expect an update in the Interval
214     EXPECT_EQ(expireTimeMs, wdog->interval());
215 }
216 
217 /** @brief Make sure the Interval can be updated while the timer is running.
218  */
219 TEST_F(WdogTest, verifyIntervalUpdateRunning)
220 {
221     const auto oldInterval = milliseconds(wdog->interval());
222     const auto newInterval = 5s;
223 
224     EXPECT_TRUE(wdog->enabled(true));
225     auto remaining = milliseconds(wdog->timeRemaining());
226     EXPECT_GE(oldInterval, remaining);
227     EXPECT_LE(oldInterval - Quantum(1), remaining);
228     EXPECT_EQ(newInterval,
229               milliseconds(wdog->interval(milliseconds(newInterval).count())));
230 
231     // Expect only the interval to update
232     remaining = milliseconds(wdog->timeRemaining());
233     EXPECT_GE(oldInterval, remaining);
234     EXPECT_LE(oldInterval - Quantum(1), remaining);
235     EXPECT_EQ(newInterval, milliseconds(wdog->interval()));
236 
237     // Expect reset to use the new interval
238     wdog->resetTimeRemaining(false);
239     remaining = milliseconds(wdog->timeRemaining());
240     EXPECT_GE(newInterval, remaining);
241     EXPECT_LE(newInterval - Quantum(1), remaining);
242 }
243 
244 /** @brief Make sure that watchdog is started and enabled.
245  *         Wait default interval quantums and make sure that wdog has died
246  */
247 TEST_F(WdogTest, enableWdogAndWaitTillEnd)
248 {
249     // Enable and then verify
250     EXPECT_TRUE(wdog->enabled(true));
251 
252     // Waiting default expiration
253     EXPECT_EQ(defaultInterval - Quantum(1), waitForWatchdog(defaultInterval));
254 
255     EXPECT_FALSE(wdog->enabled());
256     EXPECT_EQ(0, wdog->timeRemaining());
257     EXPECT_TRUE(wdog->timerExpired());
258     EXPECT_FALSE(wdog->timerEnabled());
259 }
260 
261 /** @brief Make sure the watchdog is started and enabled with a fallback
262  *         Wait through the initial trip and ensure the fallback is observed
263  *         Make sure that fallback runs to completion and ensure the watchdog
264  *         is disabled
265  */
266 TEST_F(WdogTest, enableWdogWithFallbackTillEnd)
267 {
268     auto primaryInterval = Quantum(5);
269     auto primaryIntervalMs = milliseconds(primaryInterval).count();
270     auto fallbackInterval = primaryInterval * 2;
271     auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
272 
273     // We need to make a wdog with the right fallback options
274     // The interval is set to be noticeably different from the default
275     // so we can always tell the difference
276     Watchdog::Fallback fallback;
277     fallback.action = Watchdog::Action::PowerOff;
278     fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
279     fallback.always = false;
280     wdog.reset();
281     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
282                                       Watchdog::ActionTargetMap(), fallback);
283     EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
284     EXPECT_FALSE(wdog->enabled());
285     EXPECT_EQ(0, wdog->timeRemaining());
286 
287     // Enable and then verify
288     EXPECT_TRUE(wdog->enabled(true));
289 
290     // Waiting default expiration
291     EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
292 
293     // We should now have entered the fallback once the primary expires
294     EXPECT_FALSE(wdog->enabled());
295     auto remaining = milliseconds(wdog->timeRemaining());
296     EXPECT_GE(fallbackInterval, remaining);
297     EXPECT_LT(primaryInterval, remaining);
298     EXPECT_FALSE(wdog->timerExpired());
299     EXPECT_TRUE(wdog->timerEnabled());
300 
301     // We should still be ticking in fallback when setting action or interval
302     auto newInterval = primaryInterval - Quantum(1);
303     auto newIntervalMs = milliseconds(newInterval).count();
304     EXPECT_EQ(newInterval, milliseconds(wdog->interval(newIntervalMs)));
305     EXPECT_EQ(Watchdog::Action::None,
306               wdog->expireAction(Watchdog::Action::None));
307 
308     EXPECT_FALSE(wdog->enabled());
309     EXPECT_GE(remaining, milliseconds(wdog->timeRemaining()));
310     EXPECT_LT(primaryInterval, milliseconds(wdog->timeRemaining()));
311     EXPECT_FALSE(wdog->timerExpired());
312     EXPECT_TRUE(wdog->timerEnabled());
313 
314     // Test that setting the timeRemaining always resets the timer to the
315     // fallback interval
316     EXPECT_EQ(fallback.interval, wdog->timeRemaining(primaryInterval.count()));
317     EXPECT_FALSE(wdog->enabled());
318 
319     remaining = milliseconds(wdog->timeRemaining());
320     EXPECT_GE(fallbackInterval, remaining);
321     EXPECT_LE(fallbackInterval - Quantum(1), remaining);
322     EXPECT_FALSE(wdog->timerExpired());
323     EXPECT_TRUE(wdog->timerEnabled());
324 
325     // Waiting fallback expiration
326     EXPECT_EQ(fallbackInterval - Quantum(1), waitForWatchdog(fallbackInterval));
327 
328     // We should now have disabled the watchdog after the fallback expires
329     EXPECT_FALSE(wdog->enabled());
330     EXPECT_EQ(0, wdog->timeRemaining());
331     EXPECT_TRUE(wdog->timerExpired());
332     EXPECT_FALSE(wdog->timerEnabled());
333 
334     // Make sure enabling the watchdog again works
335     EXPECT_TRUE(wdog->enabled(true));
336 
337     // We should have re-entered the primary
338     EXPECT_TRUE(wdog->enabled());
339     EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
340     EXPECT_FALSE(wdog->timerExpired());
341     EXPECT_TRUE(wdog->timerEnabled());
342 }
343 
344 /** @brief Make sure the watchdog is started and enabled with a fallback
345  *         Wait through the initial trip and ensure the fallback is observed
346  *         Make sure that we can re-enable the watchdog during fallback
347  */
348 TEST_F(WdogTest, enableWdogWithFallbackReEnable)
349 {
350     auto primaryInterval = Quantum(5);
351     auto primaryIntervalMs = milliseconds(primaryInterval).count();
352     auto fallbackInterval = primaryInterval * 2;
353     auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
354 
355     // We need to make a wdog with the right fallback options
356     // The interval is set to be noticeably different from the default
357     // so we can always tell the difference
358     Watchdog::Fallback fallback;
359     fallback.action = Watchdog::Action::PowerOff;
360     fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
361     fallback.always = false;
362     wdog.reset();
363     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
364                                       Watchdog::ActionTargetMap(), 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     EXPECT_TRUE(wdog->enabled(true));
386 
387     // We should have re-entered the primary
388     EXPECT_TRUE(wdog->enabled());
389     EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
390     EXPECT_FALSE(wdog->timerExpired());
391     EXPECT_TRUE(wdog->timerEnabled());
392 }
393 
394 /** @brief Make sure the watchdog is started and enabled with a fallback
395  *         Wait through the initial trip and ensure the fallback is observed
396  *         Make sure that changing the primary interval and calling reset timer
397  *         will enable the primary watchdog with primary interval.
398  */
399 TEST_F(WdogTest, enableWdogWithFallbackResetTimerEnable)
400 {
401     auto primaryInterval = Quantum(5);
402     auto primaryIntervalMs = milliseconds(primaryInterval).count();
403     auto fallbackInterval = primaryInterval * 2;
404     auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
405     auto newInterval = fallbackInterval * 2;
406     auto newIntervalMs = milliseconds(newInterval).count();
407 
408     // We need to make a wdog with the right fallback options
409     // The interval is set to be noticeably different from the default
410     // so we can always tell the difference
411     Watchdog::Fallback fallback;
412     fallback.action = Watchdog::Action::PowerOff;
413     fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
414     fallback.always = false;
415     wdog.reset();
416     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
417                                       Watchdog::ActionTargetMap(), fallback);
418     EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
419     EXPECT_FALSE(wdog->enabled());
420     EXPECT_EQ(0, wdog->timeRemaining());
421     EXPECT_FALSE(wdog->timerExpired());
422     EXPECT_FALSE(wdog->timerEnabled());
423 
424     // Enable and then verify
425     EXPECT_TRUE(wdog->enabled(true));
426 
427     // Waiting default expiration
428     EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
429 
430     // We should now have entered the fallback once the primary expires
431     EXPECT_FALSE(wdog->enabled());
432     auto remaining = milliseconds(wdog->timeRemaining());
433     EXPECT_GE(fallbackInterval, remaining);
434     EXPECT_LT(primaryInterval, remaining);
435     EXPECT_FALSE(wdog->timerExpired());
436     EXPECT_TRUE(wdog->timerEnabled());
437 
438     // Setting the interval should take effect once resetTimer re-enables wdog
439     EXPECT_EQ(newIntervalMs, wdog->interval(newIntervalMs));
440     wdog->resetTimeRemaining(true);
441 
442     // We should have re-entered the primary
443     EXPECT_TRUE(wdog->enabled());
444     remaining = milliseconds(wdog->timeRemaining());
445     EXPECT_GE(newInterval, remaining);
446     EXPECT_LE(newInterval - Quantum(1), remaining);
447     EXPECT_FALSE(wdog->timerExpired());
448     EXPECT_TRUE(wdog->timerEnabled());
449 }
450 
451 /** @brief Make sure the watchdog is started and with a fallback without
452  *         sending an enable
453  *         Then enable the watchdog
454  *         Wait through the initial trip and ensure the fallback is observed
455  *         Make sure that fallback runs to completion and ensure the watchdog
456  *         is in the fallback state again
457  */
458 TEST_F(WdogTest, enableWdogWithFallbackAlways)
459 {
460     auto primaryInterval = Quantum(5);
461     auto primaryIntervalMs = milliseconds(primaryInterval).count();
462     auto fallbackInterval = primaryInterval * 2;
463     auto fallbackIntervalMs = milliseconds(fallbackInterval).count();
464 
465     // We need to make a wdog with the right fallback options
466     // The interval is set to be noticeably different from the default
467     // so we can always tell the difference
468     Watchdog::Fallback fallback;
469     fallback.action = Watchdog::Action::PowerOff;
470     fallback.interval = static_cast<uint64_t>(fallbackIntervalMs);
471     fallback.always = true;
472     wdog.reset();
473     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
474                                       Watchdog::ActionTargetMap(), fallback,
475                                       milliseconds(TEST_MIN_INTERVAL).count());
476 
477     // Make sure defualt interval is biggger than min interval
478     EXPECT_LT(milliseconds((TEST_MIN_INTERVAL).count()),
479               milliseconds(wdog->interval()));
480 
481     EXPECT_EQ(primaryInterval, milliseconds(wdog->interval(primaryIntervalMs)));
482     EXPECT_FALSE(wdog->enabled());
483     auto remaining = milliseconds(wdog->timeRemaining());
484     EXPECT_GE(fallbackInterval, remaining);
485     EXPECT_LT(primaryInterval, remaining);
486     EXPECT_FALSE(wdog->timerExpired());
487     EXPECT_TRUE(wdog->timerEnabled());
488 
489     // Enable and then verify
490     EXPECT_TRUE(wdog->enabled(true));
491     EXPECT_GE(primaryInterval, milliseconds(wdog->timeRemaining()));
492 
493     // Waiting default expiration
494     EXPECT_EQ(primaryInterval - Quantum(1), waitForWatchdog(primaryInterval));
495 
496     // We should now have entered the fallback once the primary expires
497     EXPECT_FALSE(wdog->enabled());
498     remaining = milliseconds(wdog->timeRemaining());
499     EXPECT_GE(fallbackInterval, remaining);
500     EXPECT_LT(primaryInterval, remaining);
501     EXPECT_FALSE(wdog->timerExpired());
502     EXPECT_TRUE(wdog->timerEnabled());
503 
504     // Waiting fallback expiration
505     EXPECT_EQ(fallbackInterval - Quantum(1), waitForWatchdog(fallbackInterval));
506 
507     // We should now enter the fallback again
508     EXPECT_FALSE(wdog->enabled());
509     remaining = milliseconds(wdog->timeRemaining());
510     EXPECT_GE(fallbackInterval, remaining);
511     EXPECT_LT(primaryInterval, remaining);
512     EXPECT_FALSE(wdog->timerExpired());
513     EXPECT_TRUE(wdog->timerEnabled());
514 }
515 
516 /** @brief Test minimal interval
517  *  The minimal interval was set 2 seconds
518  *  Test that when setting interval to 1s , it is still returning 2s
519  */
520 TEST_F(WdogTest, verifyMinIntervalSetting)
521 {
522     auto newInterval = Quantum(1);
523     auto newIntervalMs = milliseconds(newInterval).count();
524     auto minIntervalMs = milliseconds(TEST_MIN_INTERVAL).count();
525 
526     // Check first that the current interval is greater than minInterval
527     EXPECT_LT(minIntervalMs, wdog->interval());
528     // Check that the interval was not set to smaller value than minInterval
529     EXPECT_EQ(minIntervalMs, wdog->interval(newIntervalMs));
530     // Check that the interval was not set to smaller value than minInterval
531     EXPECT_EQ(minIntervalMs, wdog->interval());
532 }
533 
534 /** @brief Test minimal interval
535  *  Initiate default Watchdog in order to get the default
536  *  interval.
537  *  Initiate watchdog with minInterval greater than default
538  *  interval, and make sure the default interval was set to the
539  *  minInterval.
540  */
541 TEST_F(WdogTest, verifyConstructorMinIntervalSetting)
542 {
543     // Initiate default Watchdog and get the default interval value.
544     wdog.reset();
545     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event);
546     auto defaultIntervalMs = wdog->interval();
547     auto defaultInterval = milliseconds(defaultIntervalMs);
548     auto minInterval = defaultInterval + Quantum(30);
549     auto minIntervalMs = milliseconds(minInterval).count();
550 
551     // We initiate a new Watchdog with min interval greater than the default
552     // intrval
553     wdog.reset();
554     wdog = std::make_unique<Watchdog>(bus, TEST_PATH, event,
555                                       Watchdog::ActionTargetMap(), std::nullopt,
556                                       minIntervalMs);
557     // Check that the interval was set to the minInterval
558     EXPECT_EQ(minIntervalMs, wdog->interval());
559 
560     // Enable and then verify
561     EXPECT_TRUE(wdog->enabled(true));
562     EXPECT_FALSE(wdog->timerExpired());
563     EXPECT_TRUE(wdog->timerEnabled());
564 
565     // Set remaining time shorter than minInterval will actually set it to
566     // minInterval
567     auto remaining = milliseconds(wdog->timeRemaining(defaultIntervalMs));
568 
569     // Its possible that we are off by few msecs depending on
570     // how we get scheduled. So checking a range here.
571     EXPECT_TRUE((remaining >= minInterval - Quantum(1)) &&
572                 (remaining <= minInterval));
573 
574     EXPECT_FALSE(wdog->timerExpired());
575     EXPECT_TRUE(wdog->timerEnabled());
576 }
577 
578 } // namespace watchdog
579 } // namespace phosphor
580