1 // Copyright (c) 2006-2008 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 5 // Tests for Watchdog class. 6 7 #include "base/platform_thread.h" 8 #include "base/spin_wait.h" 9 #include "base/time.h" 10 #include "base/watchdog.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 using base::TimeDelta; 14 15 namespace { 16 17 //------------------------------------------------------------------------------ 18 // Provide a derived class to facilitate testing. 19 20 class WatchdogCounter : public Watchdog { 21 public: 22 WatchdogCounter(const TimeDelta& duration, 23 const std::string& thread_watched_name, 24 bool enabled) 25 : Watchdog(duration, thread_watched_name, enabled), alarm_counter_(0) { 26 } 27 28 virtual ~WatchdogCounter() {} 29 30 virtual void Alarm() { 31 alarm_counter_++; 32 Watchdog::Alarm(); 33 } 34 35 int alarm_counter() { return alarm_counter_; } 36 37 private: 38 int alarm_counter_; 39 40 DISALLOW_COPY_AND_ASSIGN(WatchdogCounter); 41 }; 42 43 class WatchdogTest : public testing::Test { 44 public: 45 void SetUp() { 46 Watchdog::ResetStaticData(); 47 } 48 }; 49 50 51 //------------------------------------------------------------------------------ 52 // Actual tests 53 54 // Minimal constructor/destructor test. 55 TEST_F(WatchdogTest, StartupShutdownTest) { 56 Watchdog watchdog1(TimeDelta::FromMilliseconds(300), "Disabled", false); 57 Watchdog watchdog2(TimeDelta::FromMilliseconds(300), "Enabled", true); 58 } 59 60 // Test ability to call Arm and Disarm repeatedly. 61 TEST_F(WatchdogTest, ArmDisarmTest) { 62 Watchdog watchdog1(TimeDelta::FromMilliseconds(300), "Disabled", false); 63 watchdog1.Arm(); 64 watchdog1.Disarm(); 65 watchdog1.Arm(); 66 watchdog1.Disarm(); 67 68 Watchdog watchdog2(TimeDelta::FromMilliseconds(300), "Enabled", true); 69 watchdog2.Arm(); 70 watchdog2.Disarm(); 71 watchdog2.Arm(); 72 watchdog2.Disarm(); 73 } 74 75 // Make sure a basic alarm fires when the time has expired. 76 TEST_F(WatchdogTest, AlarmTest) { 77 WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), "Enabled", true); 78 watchdog.Arm(); 79 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5), 80 watchdog.alarm_counter() > 0); 81 EXPECT_EQ(1, watchdog.alarm_counter()); 82 } 83 84 // Make sure a basic alarm fires when the time has expired. 85 TEST_F(WatchdogTest, AlarmPriorTimeTest) { 86 WatchdogCounter watchdog(TimeDelta::TimeDelta(), "Enabled2", true); 87 // Set a time in the past. 88 watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(2)); 89 // It should instantly go off, but certainly in less than 5 minutes. 90 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5), 91 watchdog.alarm_counter() > 0); 92 93 EXPECT_EQ(1, watchdog.alarm_counter()); 94 } 95 96 // Make sure a disable alarm does nothing, even if we arm it. 97 TEST_F(WatchdogTest, ConstructorDisabledTest) { 98 WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), "Disabled", false); 99 watchdog.Arm(); 100 // Alarm should not fire, as it was disabled. 101 PlatformThread::Sleep(500); 102 EXPECT_EQ(0, watchdog.alarm_counter()); 103 } 104 105 // Make sure Disarming will prevent firing, even after Arming. 106 TEST_F(WatchdogTest, DisarmTest) { 107 WatchdogCounter watchdog(TimeDelta::FromSeconds(5), "Enabled3", true); 108 watchdog.Arm(); 109 PlatformThread::Sleep(100); // Don't sleep too long 110 watchdog.Disarm(); 111 // Alarm should not fire. 112 PlatformThread::Sleep(5500); 113 EXPECT_EQ(0, watchdog.alarm_counter()); 114 115 // ...but even after disarming, we can still use the alarm... 116 // Set a time greater than the timeout into the past. 117 watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(10)); 118 // It should almost instantly go off, but certainly in less than 5 minutes. 119 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5), 120 watchdog.alarm_counter() > 0); 121 122 EXPECT_EQ(1, watchdog.alarm_counter()); 123 } 124 125 } // namespace 126