Home | History | Annotate | Download | only in base
      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