add common timer.hpp unit tests

Add unit tests for timer.hpp class. These are the unit tests copied from
the phosphor-host-ipmid/softoff/test directory.

Change-Id: I9d74c6eb528f652965f43a3a4b973368ed782bf0
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 5848c67..a2ea724 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -10,7 +10,7 @@
 AM_CXXFLAGS = $(CODE_COVERAGE_CXXFLAGS)
 test_ldadd = $(top_builddir)/libsdbusplus.la $(SYSTEMD_LIBS) \
              $(OESDK_TESTCASE_FLAGS) $(CODE_COVERAGE_LIBS)
-gtest_ldadd = $(test_ldadd) $(GTEST_LIBS) $(GMOCK_LIBS) -lgmock_main
+gtest_ldadd = $(test_ldadd) $(GTEST_LIBS) $(GMOCK_LIBS) -lgmock_main -lpthread
 
 check_PROGRAMS =
 TESTS = $(check_PROGRAMS)
@@ -55,4 +55,8 @@
 vtable_vtable_SOURCES = vtable/vtable.cpp vtable/vtable_c.c
 vtable_vtable_LDADD = $(gtest_ldadd)
 
+check_PROGRAMS += timer
+timer_SOURCES = timer.cpp
+timer_LDADD = $(gtest_ldadd)
+
 endif
diff --git a/test/timer.cpp b/test/timer.cpp
new file mode 100644
index 0000000..f27fc6e
--- /dev/null
+++ b/test/timer.cpp
@@ -0,0 +1,262 @@
+#include <chrono>
+#include <iostream>
+#include <sdbusplus/timer.hpp>
+
+#include <gtest/gtest.h>
+
+using namespace phosphor;
+
+class TimerTest : public ::testing::Test
+{
+  public:
+    // systemd event handler
+    sd_event* events;
+
+    // Need this so that events can be initialized.
+    int rc;
+
+    // Source of event
+    sd_event_source* eventSource = nullptr;
+
+    // Add a Timer Object
+    Timer timer;
+
+    // Gets called as part of each TEST_F construction
+    TimerTest() : rc(sd_event_default(&events)), timer(events)
+    {
+        // Check for successful creation of
+        // event handler and timer object.
+        EXPECT_GE(rc, 0);
+    }
+
+    // Gets called as part of each TEST_F destruction
+    ~TimerTest()
+    {
+        events = sd_event_unref(events);
+    }
+};
+
+class TimerTestCallBack : public ::testing::Test
+{
+  public:
+    // systemd event handler
+    sd_event* events;
+
+    // Need this so that events can be initialized.
+    int rc;
+
+    // Source of event
+    sd_event_source* eventSource = nullptr;
+
+    // Add a Timer Object
+    std::unique_ptr<Timer> timer = nullptr;
+
+    // Indicates optional call back fun was called
+    bool callBackDone = false;
+
+    void callBack()
+    {
+        callBackDone = true;
+    }
+
+    // Gets called as part of each TEST_F construction
+    TimerTestCallBack() : rc(sd_event_default(&events))
+
+    {
+        // Check for successful creation of
+        // event handler and timer object.
+        EXPECT_GE(rc, 0);
+
+        std::function<void()> func(
+            std::bind(&TimerTestCallBack::callBack, this));
+        timer = std::make_unique<Timer>(events, func);
+    }
+
+    // Gets called as part of each TEST_F destruction
+    ~TimerTestCallBack()
+    {
+        events = sd_event_unref(events);
+    }
+};
+
+/** @brief Makes sure that timer is expired and the
+ *  callback handler gets invoked post 2 seconds
+ */
+TEST_F(TimerTest, timerExpiresAfter2seconds)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Waiting 2 seconds is enough here since we have
+    // already spent some usec now
+    int count = 0;
+    while (count < 2 && !timer.isExpired())
+    {
+        // Returns -0- on timeout and positive number on dispatch
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(true, timer.isExpired());
+    EXPECT_EQ(1, count);
+}
+
+/** @brief Makes sure that timer is not expired
+ */
+TEST_F(TimerTest, timerNotExpiredAfter2Seconds)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Now turn off the timer post a 1 second sleep
+    sleep(1);
+    EXPECT_GE(timer.stop(), 0);
+
+    // Wait 2 seconds and see that timer is not expired
+    int count = 0;
+    while (count < 2)
+    {
+        // Returns -0- on timeout
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(false, timer.isExpired());
+
+    // 2 because of one more count that happens prior to exiting
+    EXPECT_EQ(2, count);
+}
+
+/** @brief Makes sure that timer value is changed in between
+ *  and that the new timer expires
+ */
+TEST_F(TimerTest, updateTimerAndExpectExpire)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Now sleep for a second and then set the new timeout value
+    sleep(1);
+
+    // New timeout is 3 seconds from THIS point.
+    time = duration_cast<microseconds>(seconds(3));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Wait 3 seconds and see that timer is expired
+    int count = 0;
+    while (count < 3 && !timer.isExpired())
+    {
+        // Returns -0- on timeout
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(true, timer.isExpired());
+    EXPECT_EQ(2, count);
+}
+
+/** @brief Makes sure that timer value is changed in between
+ *  and turn off and make sure that timer does not expire
+ */
+TEST_F(TimerTest, updateTimerAndNeverExpire)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Now sleep for a second and then set the new timeout value
+    sleep(1);
+
+    // New timeout is 2 seconds from THIS point.
+    time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer.start(time), 0);
+
+    // Now turn off the timer post a 1 second sleep
+    sleep(1);
+    EXPECT_GE(timer.stop(), 0);
+
+    // Wait 2 seconds and see that timer is expired
+    int count = 0;
+    while (count < 2)
+    {
+        // Returns -0- on timeout
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(false, timer.isExpired());
+
+    // 2 because of one more count that happens prior to exiting
+    EXPECT_EQ(2, count);
+}
+
+/** @brief Makes sure that optional callback is called */
+TEST_F(TimerTestCallBack, optionalFuncCallBackDone)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer->start(time), 0);
+
+    // Waiting 2 seconds is enough here since we have
+    // already spent some usec now
+    int count = 0;
+    while (count < 2 && !timer->isExpired())
+    {
+        // Returns -0- on timeout and positive number on dispatch
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(true, timer->isExpired());
+    EXPECT_EQ(true, callBackDone);
+    EXPECT_EQ(1, count);
+}
+
+/** @brief Makes sure that timer is not expired
+ */
+TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack)
+{
+    using namespace std::chrono;
+
+    auto time = duration_cast<microseconds>(seconds(2));
+    EXPECT_GE(timer->start(time), 0);
+
+    // Now turn off the timer post a 1 second sleep
+    sleep(1);
+    EXPECT_GE(timer->stop(), 0);
+
+    // Wait 2 seconds and see that timer is not expired
+    int count = 0;
+    while (count < 2)
+    {
+        // Returns -0- on timeout
+        auto sleepTime = duration_cast<microseconds>(seconds(1));
+        if (!sd_event_run(events, sleepTime.count()))
+        {
+            count++;
+        }
+    }
+    EXPECT_EQ(false, timer->isExpired());
+    EXPECT_EQ(false, callBackDone);
+
+    // 2 because of one more count that happens prior to exiting
+    EXPECT_EQ(2, count);
+}