test: split up long-running tests

gtests runs testcases sequentially as part of a test suite which is
causing long test runs. Split up the tests into separate files to
optimize test run duration.

Test suite definition is done via `suite.hpp`/`suite.cpp`.

There is a tradeoff here since the test folder structure now does not
directly mirror the source folder structure anymore. The folder name
is chosen to clarify which implementation file is being tested.

Timeouts inside testcases are not touched, it is assumed these were
chosen correctly.

In case of fdio_timed there is dependency on a folder, which is made
unique via `getpid()` call to avoid races.

Command: `time ninja -C build test`

Before: (as of current master branch, commit
`c6fee5a94bbb4b4fbb6212942f0f2cfa3049c255`)
```
real 0m18.581s
user 0m9.977s
sys 0m5.494s
```

After:
```
real 0m6.430s
user 0m10.021s
sys  0m5.501s
```

Change-Id: I2ba096cb8f9d8ffcc146448d22b7e75a1c25d103
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/test/timer/meson.build b/test/timer/meson.build
new file mode 100644
index 0000000..be9432a
--- /dev/null
+++ b/test/timer/meson.build
@@ -0,0 +1,19 @@
+timer_tests = [
+    'timer_callback_done',
+    'timer_callback_not_done',
+    'timer_expire',
+    'timer_not_expire',
+    'timer_update_expire',
+    'timer_update_not_expire',
+]
+
+foreach t : timer_tests
+    test(
+        'test_' + t.underscorify(),
+        executable(
+            'test-' + t.underscorify(),
+            t + '.cpp',
+            dependencies: [gtest_dep, gmock_dep, sdbusplus_dep],
+        ),
+    )
+endforeach
diff --git a/test/timer/suite.hpp b/test/timer/suite.hpp
new file mode 100644
index 0000000..868c5e5
--- /dev/null
+++ b/test/timer/suite.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <sdbusplus/timer.hpp>
+
+#include <gtest/gtest.h>
+
+using sdbusplus::Timer;
+
+class TimerTest : public ::testing::Test
+{
+  public:
+    // systemd event handler
+    sd_event* events = nullptr;
+
+    // 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() override
+    {
+        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() override
+    {
+        events = sd_event_unref(events);
+    }
+};
diff --git a/test/timer/timer_callback_done.cpp b/test/timer/timer_callback_done.cpp
new file mode 100644
index 0000000..29ab72b
--- /dev/null
+++ b/test/timer/timer_callback_done.cpp
@@ -0,0 +1,32 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}
diff --git a/test/timer/timer_callback_not_done.cpp b/test/timer/timer_callback_not_done.cpp
new file mode 100644
index 0000000..a74f600
--- /dev/null
+++ b/test/timer/timer_callback_not_done.cpp
@@ -0,0 +1,38 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}
diff --git a/test/timer/timer_expire.cpp b/test/timer/timer_expire.cpp
new file mode 100644
index 0000000..f84b4ed
--- /dev/null
+++ b/test/timer/timer_expire.cpp
@@ -0,0 +1,33 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}
diff --git a/test/timer/timer_not_expire.cpp b/test/timer/timer_not_expire.cpp
new file mode 100644
index 0000000..5503d0a
--- /dev/null
+++ b/test/timer/timer_not_expire.cpp
@@ -0,0 +1,37 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}
diff --git a/test/timer/timer_update_expire.cpp b/test/timer/timer_update_expire.cpp
new file mode 100644
index 0000000..47a4fa6
--- /dev/null
+++ b/test/timer/timer_update_expire.cpp
@@ -0,0 +1,39 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}
diff --git a/test/timer/timer_update_not_expire.cpp b/test/timer/timer_update_not_expire.cpp
new file mode 100644
index 0000000..b6e9fc2
--- /dev/null
+++ b/test/timer/timer_update_not_expire.cpp
@@ -0,0 +1,45 @@
+#include "suite.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+#include <chrono>
+
+#include <gtest/gtest.h>
+
+/** @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);
+}