Roll breakpad a513e85:7caf028 (svn 1384:1385)
[chromium-blink-merge.git] / base / threading / watchdog_unittest.cc
blob7a4be4c764ca72b1584b2bebac76d4bd71c874d4
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.
5 #include "base/threading/watchdog.h"
7 #include "base/logging.h"
8 #include "base/synchronization/spin_wait.h"
9 #include "base/threading/platform_thread.h"
10 #include "base/time/time.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace base {
15 namespace {
17 //------------------------------------------------------------------------------
18 // Provide a derived class to facilitate testing.
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),
26 alarm_counter_(0) {
29 virtual ~WatchdogCounter() {}
31 virtual void Alarm() OVERRIDE {
32 alarm_counter_++;
33 Watchdog::Alarm();
36 int alarm_counter() { return alarm_counter_; }
38 private:
39 int alarm_counter_;
41 DISALLOW_COPY_AND_ASSIGN(WatchdogCounter);
44 class WatchdogTest : public testing::Test {
45 public:
46 virtual void SetUp() OVERRIDE {
47 Watchdog::ResetStaticData();
51 } // namespace
53 //------------------------------------------------------------------------------
54 // Actual tests
56 // Minimal constructor/destructor test.
57 TEST_F(WatchdogTest, StartupShutdownTest) {
58 Watchdog watchdog1(TimeDelta::FromMilliseconds(300), "Disabled", false);
59 Watchdog watchdog2(TimeDelta::FromMilliseconds(300), "Enabled", true);
62 // Test ability to call Arm and Disarm repeatedly.
63 TEST_F(WatchdogTest, ArmDisarmTest) {
64 Watchdog watchdog1(TimeDelta::FromMilliseconds(300), "Disabled", false);
65 watchdog1.Arm();
66 watchdog1.Disarm();
67 watchdog1.Arm();
68 watchdog1.Disarm();
70 Watchdog watchdog2(TimeDelta::FromMilliseconds(300), "Enabled", true);
71 watchdog2.Arm();
72 watchdog2.Disarm();
73 watchdog2.Arm();
74 watchdog2.Disarm();
77 // Make sure a basic alarm fires when the time has expired.
78 TEST_F(WatchdogTest, AlarmTest) {
79 WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), "Enabled", true);
80 watchdog.Arm();
81 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5),
82 watchdog.alarm_counter() > 0);
83 EXPECT_EQ(1, watchdog.alarm_counter());
86 // Make sure a basic alarm fires when the time has expired.
87 TEST_F(WatchdogTest, AlarmPriorTimeTest) {
88 WatchdogCounter watchdog(TimeDelta(), "Enabled2", true);
89 // Set a time in the past.
90 watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(2));
91 // It should instantly go off, but certainly in less than 5 minutes.
92 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5),
93 watchdog.alarm_counter() > 0);
95 EXPECT_EQ(1, watchdog.alarm_counter());
98 // Make sure a disable alarm does nothing, even if we arm it.
99 TEST_F(WatchdogTest, ConstructorDisabledTest) {
100 WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), "Disabled", false);
101 watchdog.Arm();
102 // Alarm should not fire, as it was disabled.
103 PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
104 EXPECT_EQ(0, watchdog.alarm_counter());
107 // Make sure Disarming will prevent firing, even after Arming.
108 TEST_F(WatchdogTest, DisarmTest) {
109 WatchdogCounter watchdog(TimeDelta::FromSeconds(1), "Enabled3", true);
111 TimeTicks start = TimeTicks::Now();
112 watchdog.Arm();
113 // Sleep a bit, but not past the alarm point.
114 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
115 watchdog.Disarm();
116 TimeTicks end = TimeTicks::Now();
118 if (end - start > TimeDelta::FromMilliseconds(500)) {
119 LOG(WARNING) << "100ms sleep took over 500ms, making the results of this "
120 << "timing-sensitive test suspicious. Aborting now.";
121 return;
124 // Alarm should not have fired before it was disarmed.
125 EXPECT_EQ(0, watchdog.alarm_counter());
127 // Sleep past the point where it would have fired if it wasn't disarmed,
128 // and verify that it didn't fire.
129 PlatformThread::Sleep(TimeDelta::FromSeconds(1));
130 EXPECT_EQ(0, watchdog.alarm_counter());
132 // ...but even after disarming, we can still use the alarm...
133 // Set a time greater than the timeout into the past.
134 watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(10));
135 // It should almost instantly go off, but certainly in less than 5 minutes.
136 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(5),
137 watchdog.alarm_counter() > 0);
139 EXPECT_EQ(1, watchdog.alarm_counter());
142 } // namespace base