sched-host-tran: implement host transition process

Set the scheduled time and host transition to trigger power on/off.

Tested:
1. Check the state first
 $ curl -k -H "X-Auth-Token: $token" https://$bmc/xyz/openbmc_project/state/host0
 {
   "data": {
     "AttemptsLeft": 3,
     "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
     "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off",
     "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
     "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off",
     "RequestedTransition": "xyz.openbmc_project.State.Host.Transition.On",
     "ScheduledTime": 0
   },
   "message": "200 OK",
   "status": "ok"
 }
2. Set a time in future
 # busctl set-property xyz.openbmc_project.State.ScheduledHostTransition \
   /xyz/openbmc_project/state/host0 \
   xyz.openbmc_project.State.ScheduledHostTransition ScheduledTime t 1582184830
 # busctl get-property xyz.openbmc_project.State.ScheduledHostTransition \
   /xyz/openbmc_project/state/host0 \
   xyz.openbmc_project.State.ScheduledHostTransition ScheduledTime
   t 1582184830
3. Check the state again after scheduled time
 Jan 15 06:38:20 WS-Seq-FW-2 phosphor-host-state-manager[442]: Host State transaction request
 $ curl -k -H "X-Auth-Token: $token" https://$bmc/xyz/openbmc_project/state/host0
 {
   "data": {
     "AttemptsLeft": 3,
     "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
     "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Running",
     "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
     "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.On",
     "RequestedTransition": "xyz.openbmc_project.State.Host.Transition.On",
     "ScheduledTime": 0
   },
   "message": "200 OK",
   "status": "ok"
 }
4. Set quested transition to off
 # busctl set-property xyz.openbmc_project.State.ScheduledHostTransition \
   /xyz/openbmc_project/state/host0 \
   xyz.openbmc_project.State.ScheduledHostTransition RequestedTransition \
   s "xyz.openbmc_project.State.Host.Transition.Off"
 # busctl set-property xyz.openbmc_project.State.ScheduledHostTransition \
   /xyz/openbmc_project/state/host0 \
   xyz.openbmc_project.State.ScheduledHostTransition ScheduledTime t 1582250580
 $ curl -k -H "X-Auth-Token: $token" https://$bmc/xyz/openbmc_project/state/host0
 {
   "data": {
   "AttemptsLeft": 3,
   "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
   "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off",
   "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
   "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off"
   "RequestedTransition": "xyz.openbmc_project.State.Host.Transition.Off",
   "ScheduledTime": 0
   },
 "message": "200 OK",
 "status": "ok"
 }

Change-Id: Ib9f3a3984005d9187a9b98603ec1598d8992869e
Signed-off-by: Carol Wang <wangkair@cn.ibm.com>
diff --git a/test/test_scheduled_host_transition.cpp b/test/test_scheduled_host_transition.cpp
index f5ffa2c..58e7aea 100644
--- a/test/test_scheduled_host_transition.cpp
+++ b/test/test_scheduled_host_transition.cpp
@@ -4,6 +4,7 @@
 #include <gtest/gtest.h>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/test/sdbus_mock.hpp>
+#include <sdeventplus/event.hpp>
 #include <xyz/openbmc_project/ScheduledTime/error.hpp>
 
 namespace phosphor
@@ -20,11 +21,14 @@
 class TestScheduledHostTransition : public testing::Test
 {
   public:
+    sdeventplus::Event event;
     sdbusplus::SdBusMock sdbusMock;
     sdbusplus::bus::bus mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
     ScheduledHostTransition scheduledHostTransition;
 
-    TestScheduledHostTransition() : scheduledHostTransition(mockedBus, "")
+    TestScheduledHostTransition() :
+        event(sdeventplus::Event::get_default()),
+        scheduledHostTransition(mockedBus, "", event)
     {
         // Empty
     }
@@ -33,11 +37,17 @@
     {
         return scheduledHostTransition.getTime();
     }
+
+    bool isTimerEnabled()
+    {
+        return scheduledHostTransition.timer.isEnabled();
+    }
 };
 
 TEST_F(TestScheduledHostTransition, disableHostTransition)
 {
     EXPECT_EQ(scheduledHostTransition.scheduledTime(0), 0);
+    EXPECT_FALSE(isTimerEnabled());
 }
 
 TEST_F(TestScheduledHostTransition, invalidScheduledTime)
@@ -49,6 +59,25 @@
                  InvalidTimeError);
 }
 
+TEST_F(TestScheduledHostTransition, validScheduledTime)
+{
+    // scheduled time is 1 min later than current time
+    uint64_t schTime =
+        static_cast<uint64_t>((getCurrentTime() + seconds(60)).count());
+    EXPECT_EQ(scheduledHostTransition.scheduledTime(schTime), schTime);
+    EXPECT_TRUE(isTimerEnabled());
+}
+
+TEST_F(TestScheduledHostTransition, hostTransitionStatus)
+{
+    // set requested transition to be on
+    scheduledHostTransition.scheduledTransition(Transition::On);
+    EXPECT_EQ(scheduledHostTransition.scheduledTransition(), Transition::On);
+    // set requested transition to be off
+    scheduledHostTransition.scheduledTransition(Transition::Off);
+    EXPECT_EQ(scheduledHostTransition.scheduledTransition(), Transition::Off);
+}
+
 } // namespace manager
 } // namespace state
 } // namespace phosphor