1 #include "config.h" 2 3 #include "bmc_epoch.hpp" 4 #include "mocked_bmc_time_change_listener.hpp" 5 #include "types.hpp" 6 7 #include <memory> 8 #include <sdbusplus/bus.hpp> 9 #include <xyz/openbmc_project/Time/error.hpp> 10 11 #include <gtest/gtest.h> 12 13 namespace phosphor 14 { 15 namespace time 16 { 17 18 using ::testing::_; 19 using namespace std::chrono; 20 using NotAllowed = sdbusplus::xyz::openbmc_project::Time::Error::NotAllowed; 21 22 class TestBmcEpoch : public testing::Test 23 { 24 public: 25 sdbusplus::bus::bus bus; 26 sd_event* event; 27 MockBmcTimeChangeListener listener; 28 std::unique_ptr<BmcEpoch> bmcEpoch; 29 30 TestBmcEpoch() : bus(sdbusplus::bus::new_default()) 31 { 32 // BmcEpoch requires sd_event to init 33 sd_event_default(&event); 34 bus.attach_event(event, SD_EVENT_PRIORITY_NORMAL); 35 bmcEpoch = std::make_unique<BmcEpoch>(bus, OBJPATH_BMC); 36 bmcEpoch->setBmcTimeChangeListener(&listener); 37 } 38 39 ~TestBmcEpoch() 40 { 41 bus.detach_event(); 42 sd_event_unref(event); 43 } 44 45 // Proxies for BmcEpoch's private members and functions 46 Mode getTimeMode() 47 { 48 return bmcEpoch->timeMode; 49 } 50 Owner getTimeOwner() 51 { 52 return bmcEpoch->timeOwner; 53 } 54 void setTimeOwner(Owner owner) 55 { 56 bmcEpoch->timeOwner = owner; 57 } 58 void setTimeMode(Mode mode) 59 { 60 bmcEpoch->timeMode = mode; 61 } 62 void triggerTimeChange() 63 { 64 bmcEpoch->onTimeChange(nullptr, -1, 0, bmcEpoch.get()); 65 } 66 }; 67 68 TEST_F(TestBmcEpoch, empty) 69 { 70 // Default mode/owner is MANUAL/BOTH 71 EXPECT_EQ(Mode::Manual, getTimeMode()); 72 EXPECT_EQ(Owner::Both, getTimeOwner()); 73 } 74 75 TEST_F(TestBmcEpoch, getElapsed) 76 { 77 auto t1 = bmcEpoch->elapsed(); 78 EXPECT_NE(0, t1); 79 auto t2 = bmcEpoch->elapsed(); 80 EXPECT_GE(t2, t1); 81 } 82 83 TEST_F(TestBmcEpoch, setElapsedNotAllowed) 84 { 85 auto epochNow = 86 duration_cast<microseconds>(system_clock::now().time_since_epoch()) 87 .count(); 88 89 // In Host owner, setting time is not allowed 90 setTimeMode(Mode::Manual); 91 setTimeOwner(Owner::Host); 92 EXPECT_THROW(bmcEpoch->elapsed(epochNow), NotAllowed); 93 } 94 95 TEST_F(TestBmcEpoch, setElapsedOK) 96 { 97 // TODO: setting time will call sd-bus functions and it will fail on host 98 // if we have gmock for sdbusplus::bus, we can test setElapsed. 99 // But for now we can not test it 100 } 101 102 TEST_F(TestBmcEpoch, onTimeChange) 103 { 104 // On BMC time change, the listner is expected to be notified 105 EXPECT_CALL(listener, onBmcTimeChanged(_)).Times(1); 106 triggerTimeChange(); 107 } 108 109 } // namespace time 110 } // namespace phosphor 111