watchdog_unittest.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/threading/watchdog.h"
  5. #include "base/logging.h"
  6. #include "base/test/spin_wait.h"
  7. #include "base/threading/platform_thread.h"
  8. #include "base/time/time.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace base {
  11. namespace {
  12. //------------------------------------------------------------------------------
  13. // Provide a derived class to facilitate testing.
  14. class WatchdogCounter : public Watchdog {
  15. public:
  16. WatchdogCounter(const TimeDelta& duration,
  17. const std::string& thread_watched_name,
  18. bool enabled)
  19. : Watchdog(duration, thread_watched_name, enabled),
  20. alarm_counter_(0) {
  21. }
  22. WatchdogCounter(const WatchdogCounter&) = delete;
  23. WatchdogCounter& operator=(const WatchdogCounter&) = delete;
  24. ~WatchdogCounter() override = default;
  25. void Alarm() override {
  26. alarm_counter_++;
  27. Watchdog::Alarm();
  28. }
  29. int alarm_counter() { return alarm_counter_; }
  30. private:
  31. int alarm_counter_;
  32. };
  33. class WatchdogTest : public testing::Test {
  34. public:
  35. void SetUp() override { Watchdog::ResetStaticData(); }
  36. };
  37. } // namespace
  38. //------------------------------------------------------------------------------
  39. // Actual tests
  40. // Minimal constructor/destructor test.
  41. TEST_F(WatchdogTest, StartupShutdownTest) {
  42. Watchdog watchdog1(Milliseconds(300), "Disabled", false);
  43. Watchdog watchdog2(Milliseconds(300), "Enabled", true);
  44. }
  45. // Test ability to call Arm and Disarm repeatedly.
  46. TEST_F(WatchdogTest, ArmDisarmTest) {
  47. Watchdog watchdog1(Milliseconds(300), "Disabled", false);
  48. watchdog1.Arm();
  49. watchdog1.Disarm();
  50. watchdog1.Arm();
  51. watchdog1.Disarm();
  52. Watchdog watchdog2(Milliseconds(300), "Enabled", true);
  53. watchdog2.Arm();
  54. watchdog2.Disarm();
  55. watchdog2.Arm();
  56. watchdog2.Disarm();
  57. }
  58. // Make sure a basic alarm fires when the time has expired.
  59. TEST_F(WatchdogTest, AlarmTest) {
  60. WatchdogCounter watchdog(Milliseconds(10), "Enabled", true);
  61. watchdog.Arm();
  62. SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(Minutes(5), watchdog.alarm_counter() > 0);
  63. EXPECT_EQ(1, watchdog.alarm_counter());
  64. }
  65. // Make sure a basic alarm fires when the time has expired.
  66. TEST_F(WatchdogTest, AlarmPriorTimeTest) {
  67. WatchdogCounter watchdog(TimeDelta(), "Enabled2", true);
  68. // Set a time in the past.
  69. watchdog.ArmSomeTimeDeltaAgo(Seconds(2));
  70. // It should instantly go off, but certainly in less than 5 minutes.
  71. SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(Minutes(5), watchdog.alarm_counter() > 0);
  72. EXPECT_EQ(1, watchdog.alarm_counter());
  73. }
  74. // Make sure a disable alarm does nothing, even if we arm it.
  75. TEST_F(WatchdogTest, ConstructorDisabledTest) {
  76. WatchdogCounter watchdog(Milliseconds(10), "Disabled", false);
  77. watchdog.Arm();
  78. // Alarm should not fire, as it was disabled.
  79. PlatformThread::Sleep(Milliseconds(500));
  80. EXPECT_EQ(0, watchdog.alarm_counter());
  81. }
  82. // Make sure Disarming will prevent firing, even after Arming.
  83. TEST_F(WatchdogTest, DisarmTest) {
  84. WatchdogCounter watchdog(Seconds(1), "Enabled3", true);
  85. TimeTicks start = TimeTicks::Now();
  86. watchdog.Arm();
  87. // Sleep a bit, but not past the alarm point.
  88. PlatformThread::Sleep(Milliseconds(100));
  89. watchdog.Disarm();
  90. TimeTicks end = TimeTicks::Now();
  91. if (end - start > Milliseconds(500)) {
  92. LOG(WARNING) << "100ms sleep took over 500ms, making the results of this "
  93. << "timing-sensitive test suspicious. Aborting now.";
  94. return;
  95. }
  96. // Alarm should not have fired before it was disarmed.
  97. EXPECT_EQ(0, watchdog.alarm_counter());
  98. // Sleep past the point where it would have fired if it wasn't disarmed,
  99. // and verify that it didn't fire.
  100. PlatformThread::Sleep(Seconds(1));
  101. EXPECT_EQ(0, watchdog.alarm_counter());
  102. // ...but even after disarming, we can still use the alarm...
  103. // Set a time greater than the timeout into the past.
  104. watchdog.ArmSomeTimeDeltaAgo(Seconds(10));
  105. // It should almost instantly go off, but certainly in less than 5 minutes.
  106. SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(Minutes(5), watchdog.alarm_counter() > 0);
  107. EXPECT_EQ(1, watchdog.alarm_counter());
  108. }
  109. } // namespace base