summaryrefslogtreecommitdiffstats
path: root/base/watchdog_unittest.cc
blob: c4a664fe01c83d331c03b193d718a94825e4f61f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests for Watchdog class.

#include "base/logging.h"
#include "base/watchdog.h"
#include "base/spin_wait.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::TimeDelta;

namespace {

//------------------------------------------------------------------------------
// Provide a derived class to facilitate testing.

// TODO(JAR): Remove default argument from constructor, and make mandatory.
class WatchdogCounter : public Watchdog {
 public:
  WatchdogCounter(const TimeDelta& duration,
                  const std::wstring& thread_watched_name,
                  bool enabled = true)
      : Watchdog(duration, thread_watched_name, enabled), alarm_counter_(0) {
  }

  virtual ~WatchdogCounter() {}

  virtual void Alarm() {
    alarm_counter_++;
    Watchdog::Alarm();
  }

  int alarm_counter() { return alarm_counter_; }

 private:
  int alarm_counter_;

  DISALLOW_EVIL_CONSTRUCTORS(WatchdogCounter);
};

class WatchdogTest : public testing::Test {
};


//------------------------------------------------------------------------------
// Actual tests

// Minimal constructor/destructor test.
TEST(WatchdogTest, StartupShutdownTest) {
  Watchdog watchdog1(TimeDelta::FromMilliseconds(300), L"Disabled", false);
  Watchdog watchdog2(TimeDelta::FromMilliseconds(300), L"Enabled", true);

  // The following test is depricated, and should be removed when the
  // default argument constructor is no longer accepted.
  Watchdog watchdog3(TimeDelta::FromMilliseconds(300), L"Default");
}

// Test ability to call Arm and Disarm repeatedly.
TEST(WatchdogTest, ArmDisarmTest) {
  Watchdog watchdog1(TimeDelta::FromMilliseconds(300), L"Disabled", false);
  watchdog1.Arm();
  watchdog1.Disarm();
  watchdog1.Arm();
  watchdog1.Disarm();

  Watchdog watchdog2(TimeDelta::FromMilliseconds(300), L"Enabled", true);
  watchdog2.Arm();
  watchdog2.Disarm();
  watchdog2.Arm();
  watchdog2.Disarm();

  // The following test is depricated, and should be removed when the
  // default argument constructor is no longer accepted.
  Watchdog watchdog3(TimeDelta::FromMilliseconds(300), L"Default");
  watchdog3.Arm();
  watchdog3.Disarm();
  watchdog3.Arm();
  watchdog3.Disarm();
}

// Make sure a basic alarm fires when the time has expired.
TEST(WatchdogTest, AlarmTest) {
  WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), L"Enabled", true);
  watchdog.Arm();
  SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromSeconds(1),
                                   watchdog.alarm_counter() > 0);
  EXPECT_EQ(1, watchdog.alarm_counter());

  // Set a time greater than the timeout into the past.
  watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(2));
  // It should instantly go off, but certainly in less than a second.
  SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromSeconds(1),
                                   watchdog.alarm_counter() > 1);

  EXPECT_EQ(2, watchdog.alarm_counter());
}

// Make sure a disable alarm does nothing, even if we arm it.
TEST(WatchdogTest, ConstructorDisabledTest) {
  WatchdogCounter watchdog(TimeDelta::FromMilliseconds(10), L"Disabled", false);
  watchdog.Arm();
  // Alarm should not fire, as it was disabled.
  Sleep(500);
  EXPECT_EQ(0, watchdog.alarm_counter());
}

// Make sure Disarming will prevent firing, even after Arming.
TEST(WatchdogTest, DisarmTest) {
  WatchdogCounter watchdog(TimeDelta::FromSeconds(1), L"Enabled", true);
  watchdog.Arm();
  Sleep(100);  // Don't sleep too long
  watchdog.Disarm();
  // Alarm should not fire.
  Sleep(1500);
  EXPECT_EQ(0, watchdog.alarm_counter());

  // ...but even after disarming, we can still use the alarm...
  // Set a time greater than the timeout into the past.
  watchdog.ArmSomeTimeDeltaAgo(TimeDelta::FromSeconds(2));
  // It should almost instantly go off, but certainly in less than a second.
  SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromSeconds(1),
                                   watchdog.alarm_counter() > 0);

  EXPECT_EQ(1, watchdog.alarm_counter());
}

}  // namespace