1 #include "scheduled_host_transition.hpp"
2 
3 #include <sdbusplus/bus.hpp>
4 #include <sdbusplus/test/sdbus_mock.hpp>
5 #include <sdeventplus/event.hpp>
6 #include <xyz/openbmc_project/ScheduledTime/error.hpp>
7 
8 #include <gmock/gmock.h>
9 #include <gtest/gtest.h>
10 
11 namespace phosphor
12 {
13 namespace state
14 {
15 namespace manager
16 {
17 
18 using namespace std::chrono;
19 using InvalidTimeError =
20     sdbusplus::xyz::openbmc_project::ScheduledTime::Error::InvalidTime;
21 using HostTransition =
22     sdbusplus::xyz::openbmc_project::State::server::ScheduledHostTransition;
23 
24 class TestScheduledHostTransition : public testing::Test
25 {
26   public:
27     sdeventplus::Event event;
28     sdbusplus::SdBusMock sdbusMock;
29     sdbusplus::bus::bus mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
30     ScheduledHostTransition scheduledHostTransition;
31 
32     TestScheduledHostTransition() :
33         event(sdeventplus::Event::get_default()),
34         scheduledHostTransition(mockedBus, "", event)
35     {
36         // Empty
37     }
38 
39     seconds getCurrentTime()
40     {
41         return scheduledHostTransition.getTime();
42     }
43 
44     bool isTimerEnabled()
45     {
46         return scheduledHostTransition.timer.isEnabled();
47     }
48 
49     void bmcTimeChange()
50     {
51         scheduledHostTransition.handleTimeUpdates();
52     }
53 };
54 
55 TEST_F(TestScheduledHostTransition, disableHostTransition)
56 {
57     EXPECT_EQ(scheduledHostTransition.scheduledTime(0), 0);
58     EXPECT_FALSE(isTimerEnabled());
59 }
60 
61 TEST_F(TestScheduledHostTransition, invalidScheduledTime)
62 {
63     // scheduled time is 1 min earlier than current time
64     uint64_t schTime =
65         static_cast<uint64_t>((getCurrentTime() - seconds(60)).count());
66     EXPECT_THROW(scheduledHostTransition.scheduledTime(schTime),
67                  InvalidTimeError);
68 }
69 
70 TEST_F(TestScheduledHostTransition, validScheduledTime)
71 {
72     // scheduled time is 1 min later than current time
73     uint64_t schTime =
74         static_cast<uint64_t>((getCurrentTime() + seconds(60)).count());
75     EXPECT_EQ(scheduledHostTransition.scheduledTime(schTime), schTime);
76     EXPECT_TRUE(isTimerEnabled());
77 }
78 
79 TEST_F(TestScheduledHostTransition, hostTransitionStatus)
80 {
81     // set requested transition to be on
82     scheduledHostTransition.scheduledTransition(Transition::On);
83     EXPECT_EQ(scheduledHostTransition.scheduledTransition(), Transition::On);
84     // set requested transition to be off
85     scheduledHostTransition.scheduledTransition(Transition::Off);
86     EXPECT_EQ(scheduledHostTransition.scheduledTransition(), Transition::Off);
87 }
88 
89 TEST_F(TestScheduledHostTransition, bmcTimeChangeWithDisabledHostTransition)
90 {
91     // Disable host transition
92     scheduledHostTransition.scheduledTime(0);
93     bmcTimeChange();
94     // Check timer
95     EXPECT_FALSE(isTimerEnabled());
96     // Check scheduled time
97     EXPECT_EQ(scheduledHostTransition.HostTransition::scheduledTime(), 0);
98 }
99 
100 TEST_F(TestScheduledHostTransition, bmcTimeChangeBackward)
101 {
102     // Current time is earlier than scheduled time due to BMC time changing
103     uint64_t schTime =
104         static_cast<uint64_t>((getCurrentTime() + seconds(60)).count());
105     // Set scheduled time, which is the same as bmc time is changed.
106     // But can't use this method to write another case like
107     // bmcTimeChangeForward, because set a scheduled time earlier than current
108     // time will throw an error.
109     scheduledHostTransition.scheduledTime(schTime);
110     bmcTimeChange();
111     // Check timer
112     EXPECT_TRUE(isTimerEnabled());
113 }
114 
115 } // namespace manager
116 } // namespace state
117 } // namespace phosphor
118