From 00bd377e612a646b43e0186f84e1343f160daa0f Mon Sep 17 00:00:00 2001 From: Vishwanatha Subbanna Date: Wed, 31 May 2017 14:53:42 +0530 Subject: Add Gtest to test watchdog Change-Id: Ia0268b6b18999b6dd6cfd26bcadcff25734306f0 Signed-off-by: Vishwanatha Subbanna --- test/Makefile.am | 39 +++++++++++++++ test/timer_test.cpp | 72 +++++++++++++++++++++++++++ test/timer_test.hpp | 40 +++++++++++++++ test/watchdog_test.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ test/watchdog_test.hpp | 46 +++++++++++++++++ 5 files changed, 327 insertions(+) create mode 100644 test/Makefile.am create mode 100644 test/timer_test.cpp create mode 100644 test/timer_test.hpp create mode 100644 test/watchdog_test.cpp create mode 100644 test/watchdog_test.hpp (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..654f0f1 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,39 @@ +AM_CPPFLAGS = -I$(top_srcdir) + +# Run all 'check' test programs +TESTS = $(check_PROGRAMS) + +# Build/add utest to test suite +check_PROGRAMS = timer_test \ + watchdog_test + +utestCPPFLAGS = -Igtest \ + $(GTEST_CPPFLAGS) \ + $(AM_CPPFLAGS) \ + $(SDBUSPLUS_CFLAGS) \ + $(PHOSPHOR_LOGGING_CFLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) + +utestCXXFLAGS = $(PTHREAD_CFLAGS) + +utestLDFLAGS = -lgtest_main -lgtest \ + $(PTHREAD_LIBS) \ + $(OESDK_TESTCASE_FLAGS) \ + $(SDBUSPLUS_LIBS) \ + $(PHOSPHOR_LOGGING_LIBS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) + +timer_test_CPPFLAGS = ${utestCPPFLAGS} +timer_test_CXXFLAGS = ${utestCXXFLAGS} +timer_test_LDFLAGS = ${utestLDFLAGS} + +watchdog_test_CPPFLAGS = ${utestCPPFLAGS} +watchdog_test_CXXFLAGS = ${utestCXXFLAGS} +watchdog_test_LDFLAGS = ${utestLDFLAGS} + +timer_test_SOURCES = timer_test.cpp +watchdog_test_SOURCES = watchdog_test.cpp + +timer_test_LDADD = $(top_builddir)/timer.o +watchdog_test_LDADD = $(top_builddir)/timer.o \ + $(top_builddir)/watchdog.o diff --git a/test/timer_test.cpp b/test/timer_test.cpp new file mode 100644 index 0000000..e9f323b --- /dev/null +++ b/test/timer_test.cpp @@ -0,0 +1,72 @@ +#include +#include + +using namespace std::chrono; +using namespace std::chrono_literals; + +/** @brief Starts the timer and expects it to + * expire in configured time and expects the + * deault callback handler to kick-in + */ +TEST_F(TimerTest, testTimerForExpirationDefaultTimeoutHandler) +{ + // Expect timer to expire in 2 seconds + auto expireTime = seconds(2s); + + phosphor::watchdog::Timer timer(eventP); + + // Set the expiration and enable the timer + timer.start(duration_cast(expireTime)); + timer.setEnabled(); + + // Waiting 2 seconds to expect expiration + int count = 0; + while(count < expireTime.count() && !timer.expired()) + { + // Returns -0- on timeout and positive number on dispatch + auto sleepTime = duration_cast(seconds(1)); + if(!sd_event_run(eventP.get(), sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(true, timer.expired()); + EXPECT_EQ(expireTime.count() - 1, count); + + // Make sure secondary callback was not called. + EXPECT_EQ(false, expired); +} + +/** @brief Starts the timer and expects it to expire + * in configured time and expects the secondary + * callback to be called into along with default. + */ +TEST_F(TimerTest, testTimerForExpirationSecondCallBack) +{ + // Expect timer to expire in 2 seconds + auto expireTime = seconds(2s); + + phosphor::watchdog::Timer timer(eventP, + std::bind(&TimerTest::timeOutHandler, this)); + + // Set the expiration and enable the timer + timer.start(duration_cast(expireTime)); + timer.setEnabled(); + + // Waiting 2 seconds to expect expiration + int count = 0; + while(count < expireTime.count() && !timer.expired()) + { + // Returns -0- on timeout and positive number on dispatch + auto sleepTime = duration_cast(seconds(1)); + if(!sd_event_run(eventP.get(), sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(true, timer.expired()); + EXPECT_EQ(expireTime.count() - 1, count); + + // This gets set as part of secondary callback + EXPECT_EQ(true, expired); +} diff --git a/test/timer_test.hpp b/test/timer_test.hpp new file mode 100644 index 0000000..3f6ffea --- /dev/null +++ b/test/timer_test.hpp @@ -0,0 +1,40 @@ +#include +#include +#include + +// Base class for testing Timer +class TimerTest : public testing::Test +{ + public: + // systemd event handler + sd_event* events; + + // Need this so that events can be initialized. + int rc; + + // Tells if the watchdog timer expired. + bool expired = false; + + // Gets called as part of each TEST_F construction + TimerTest() + : rc(sd_event_default(&events)), + eventP(events) + { + // Check for successful creation of + // event handler and bus handler + EXPECT_GE(rc, 0); + + // Its already wrapped in eventP + events = nullptr; + } + + // unique_ptr for sd_event + phosphor::watchdog::EventPtr eventP; + + // Handler called by timer expiration + inline void timeOutHandler() + { + std::cout << "Time out handler called" << std::endl; + expired = true; + } +}; diff --git a/test/watchdog_test.cpp b/test/watchdog_test.cpp new file mode 100644 index 0000000..4e77528 --- /dev/null +++ b/test/watchdog_test.cpp @@ -0,0 +1,130 @@ +#include + +using namespace phosphor::watchdog; + +/** @brief Make sure that watchdog is started and not enabled */ +TEST_F(WdogTest, createWdogAndDontEnable) +{ + EXPECT_EQ(false, wdog.enabled()); + EXPECT_EQ(0, wdog.timeRemaining()); + EXPECT_EQ(false, wdog.timerExpired()); +} + +/** @brief Make sure that watchdog is started and enabled */ +TEST_F(WdogTest, createWdogAndEnable) +{ + // Enable and then verify + EXPECT_EQ(true, wdog.enabled(true)); + EXPECT_EQ(false, wdog.timerExpired()); + + // Get the configured interval + auto remaining = milliseconds(wdog.timeRemaining()); + + // Its possible that we are off by few msecs depending on + // how we get scheduled. So checking a range here. + EXPECT_TRUE((remaining >= defaultInterval - defaultDrift) && + (remaining <= defaultInterval)); + + EXPECT_EQ(false, wdog.timerExpired()); +} + +/** @brief Make sure that watchdog is started and enabled. + * Later, disable watchdog + */ +TEST_F(WdogTest, createWdogAndEnableThenDisable) +{ + // Enable and then verify + EXPECT_EQ(true, wdog.enabled(true)); + + // Disable and then verify + EXPECT_EQ(false, wdog.enabled(false)); + EXPECT_EQ(false, wdog.enabled()); + EXPECT_EQ(0, wdog.timeRemaining()); +} + +/** @brief Make sure that watchdog is started and enabled. + * Wait for 5 seconds and make sure that the remaining + * time shows 25 seconds. + */ +TEST_F(WdogTest, enableWdogAndWait5Seconds) +{ + // Enable and then verify + EXPECT_EQ(true, wdog.enabled(true)); + + // Sleep for 5 seconds + auto sleepTime = seconds(5s); + std::this_thread::sleep_for(sleepTime); + + // Get the remaining time again and expectation is that we get 25s + auto remaining = milliseconds(wdog.timeRemaining()); + auto expected = defaultInterval - + duration_cast(sleepTime); + + // Its possible that we are off by few msecs depending on + // how we get scheduled. So checking a range here. + EXPECT_TRUE((remaining >= expected - defaultDrift) && + (remaining <= expected)); + EXPECT_EQ(false, wdog.timerExpired()); +} + +/** @brief Make sure that watchdog is started and enabled. + * Wait 1 second and then reset the timer to 5 seconds + * and then expect the watchdog to expire in 5 seconds + */ +TEST_F(WdogTest, enableWdogAndResetTo5Seconds) +{ + // Enable and then verify + EXPECT_EQ(true, wdog.enabled(true)); + + // Sleep for 1 second + std::this_thread::sleep_for(1s); + + // Next timer will expire in 5 seconds from now. + auto expireTime = seconds(5s); + auto newTime = duration_cast(expireTime); + wdog.timeRemaining(newTime.count()); + + // Waiting for expiration + int count = 0; + while(count < expireTime.count() && !wdog.timerExpired()) + { + // Returns -0- on timeout and positive number on dispatch + auto sleepTime = duration_cast(seconds(1s)); + if(!sd_event_run(eventP.get(), sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(true, wdog.timerExpired()); + EXPECT_EQ(expireTime.count() - 1 , count); + + // Make sure secondary callback was not called. + EXPECT_EQ(false, expired); +} + +/** @brief Make sure that watchdog is started and enabled. + * Wait default interval seconds and make sure that wdog has died + */ +TEST_F(WdogTest, enableWdogAndWaitTillEnd) +{ + // Enable and then verify + EXPECT_EQ(true, wdog.enabled(true)); + auto expireTime = duration_cast( + milliseconds(defaultInterval)); + + // Waiting default expiration + int count = 0; + while(count < expireTime.count() && !wdog.timerExpired()) + { + // Returns -0- on timeout and positive number on dispatch + auto sleepTime = duration_cast(seconds(1s)); + if(!sd_event_run(eventP.get(), sleepTime.count())) + { + count++; + } + } + EXPECT_EQ(true, wdog.enabled()); + EXPECT_EQ(0, wdog.timeRemaining()); + EXPECT_EQ(true, wdog.timerExpired()); + EXPECT_EQ(expireTime.count() - 1, count); +} diff --git a/test/watchdog_test.hpp b/test/watchdog_test.hpp new file mode 100644 index 0000000..0d1d628 --- /dev/null +++ b/test/watchdog_test.hpp @@ -0,0 +1,46 @@ +#include +#include +#include + +using namespace std::chrono; +using namespace std::chrono_literals; + +// Test Watchdog functionality +class WdogTest : public TimerTest +{ + public: + // Gets called as part of each TEST_F construction + WdogTest() + : bus(sdbusplus::bus::new_default()), + wdog(bus, TEST_PATH, eventP), + defaultInterval(milliseconds(wdog.interval())), + defaultDrift(30) + { + // Check for successful creation of + // event handler and bus handler + EXPECT_GE(rc, 0); + + // Initially the watchdog would be disabled + EXPECT_EQ(false, wdog.enabled()); + } + + //sdbusplus handle + sdbusplus::bus::bus bus; + + // Watchdog object + phosphor::watchdog::Watchdog wdog; + + // This is the default interval as given in Interface definition + milliseconds defaultInterval; + + // Acceptable drift when we compare the interval to timeRemaining. + // This is needed since it depends on when do we get scheduled and it + // has happened that remaining time was off by few msecs. + milliseconds defaultDrift; + + private: + // Dummy name for object path + // This is just to satisfy the constructor. Does not have + // a need to check if the objects paths have been created. + static constexpr auto TEST_PATH = "/test/path"; +}; -- cgit v1.2.1