Implement HostEpoch set time logic
1. When setting host epoch, follow below logic:
Mode | Owner | Set Host Time
----- | ----- | -------------
NTP | BMC | Not allowed
NTP | HOST | Not allowed
NTP | SPLIT | OK, and just save offset
NTP | BOTH | Not allowed
MANUAL| BMC | Not allowed
MANUAL| HOST | OK, and set time to BMC
MANUAL| SPLIT | OK, and just save offset
MANUAL| BOTH | OK, and set time to BMC
2. If owner is SPLIT and BMC time is changed, update the offset accordinly;
3. Use timerfd to get notified on BMC time change, and update host time
diff accordingly;
4. Add unit test cases.
Change-Id: I2d60a821f7da9b689c579ae7ab672cc37967322c
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/test/TestBmcEpoch.cpp b/test/TestBmcEpoch.cpp
index 2fd55a5..4661e20 100644
--- a/test/TestBmcEpoch.cpp
+++ b/test/TestBmcEpoch.cpp
@@ -1,45 +1,67 @@
#include <sdbusplus/bus.hpp>
#include <gtest/gtest.h>
+#include <memory>
#include "bmc_epoch.hpp"
#include "config.h"
#include "types.hpp"
+#include "mocked_bmc_time_change_listener.hpp"
namespace phosphor
{
namespace time
{
+using ::testing::_;
using namespace std::chrono;
+
class TestBmcEpoch : public testing::Test
{
public:
sdbusplus::bus::bus bus;
- BmcEpoch bmcEpoch;
+ sd_event* event;
+ MockBmcTimeChangeListener listener;
+ std::unique_ptr<BmcEpoch> bmcEpoch;
TestBmcEpoch()
- : bus(sdbusplus::bus::new_default()),
- bmcEpoch(bus, OBJPATH_BMC)
+ : bus(sdbusplus::bus::new_default())
{
- // Empty
+ // BmcEpoch requires sd_event to init
+ sd_event_default(&event);
+ bus.attach_event(event, SD_EVENT_PRIORITY_NORMAL);
+ bmcEpoch = std::make_unique<BmcEpoch>(bus, OBJPATH_BMC);
+ bmcEpoch->setBmcTimeChangeListener(&listener);
+ }
+
+ ~TestBmcEpoch()
+ {
+ bus.detach_event();
+ sd_event_unref(event);
}
// Proxies for BmcEpoch's private members and functions
Mode getTimeMode()
{
- return bmcEpoch.timeMode;
+ return bmcEpoch->timeMode;
}
Owner getTimeOwner()
{
- return bmcEpoch.timeOwner;
+ return bmcEpoch->timeOwner;
}
void setTimeOwner(Owner owner)
{
- bmcEpoch.timeOwner = owner;
+ bmcEpoch->timeOwner = owner;
}
void setTimeMode(Mode mode)
{
- bmcEpoch.timeMode = mode;
+ bmcEpoch->timeMode = mode;
+ }
+ void triggerTimeChange()
+ {
+ bmcEpoch->onTimeChange(nullptr,
+ -1,
+ 0,
+ bmcEpoch.get());
}
};
@@ -51,9 +73,9 @@
TEST_F(TestBmcEpoch, getElapsed)
{
- auto t1 = bmcEpoch.elapsed();
+ auto t1 = bmcEpoch->elapsed();
EXPECT_NE(0, t1);
- auto t2 = bmcEpoch.elapsed();
+ auto t2 = bmcEpoch->elapsed();
EXPECT_GE(t2, t1);
}
@@ -62,13 +84,13 @@
auto epochNow = duration_cast<microseconds>(
system_clock::now().time_since_epoch()).count();
// In NTP mode, setting time is not allowed
- auto ret = bmcEpoch.elapsed(epochNow);
+ auto ret = bmcEpoch->elapsed(epochNow);
EXPECT_EQ(0, ret);
// In Host owner, setting time is not allowed
setTimeMode(Mode::MANUAL);
setTimeOwner(Owner::HOST);
- ret = bmcEpoch.elapsed(epochNow);
+ ret = bmcEpoch->elapsed(epochNow);
EXPECT_EQ(0, ret);
}
@@ -79,5 +101,12 @@
// But for now we can not test it
}
+TEST_F(TestBmcEpoch, onTimeChange)
+{
+ // On BMC time change, the listner is expected to be notified
+ EXPECT_CALL(listener, onBmcTimeChanged(_)).Times(1);
+ triggerTimeChange();
+}
+
}
}