diff options
-rw-r--r-- | manager.cpp | 79 | ||||
-rw-r--r-- | manager.hpp | 28 | ||||
-rw-r--r-- | test/TestManager.cpp | 90 | ||||
-rw-r--r-- | test/mocked_property_change_listener.hpp | 17 |
4 files changed, 174 insertions, 40 deletions
diff --git a/manager.cpp b/manager.cpp index 56e0d0b..bcc581c 100644 --- a/manager.cpp +++ b/manager.cpp @@ -134,20 +134,12 @@ void Manager::onPropertyChanged(const std::string& key, if (key == PROPERTY_TIME_MODE) { setCurrentTimeMode(value); - for (const auto listener : listeners) - { - listener->onModeChanged(timeMode); - } - // When time_mode is updated, update the NTP setting - updateNtpSetting(value); + onTimeModeChanged(value); } else if (key == PROPERTY_TIME_OWNER) { setCurrentTimeOwner(value); - for (const auto listener : listeners) - { - listener->onOwnerChanged(timeOwner); - } + onTimeOwnerChanged(); } } } @@ -259,20 +251,17 @@ void Manager::onPgoodChanged(bool pgood) } if (!requestedMode.empty()) { - setCurrentTimeMode(requestedMode); - for (const auto& listener : listeners) + if (setCurrentTimeMode(requestedMode)) { - listener->onModeChanged(timeMode); + onTimeModeChanged(requestedMode); } - updateNtpSetting(requestedMode); setRequestedMode({}); // Clear requested mode } if (!requestedOwner.empty()) { - setCurrentTimeOwner(requestedOwner); - for (const auto& listener : listeners) + if (setCurrentTimeOwner(requestedOwner)) { - listener->onOwnerChanged(timeOwner); + onTimeOwnerChanged(); } setRequestedOwner({}); // Clear requested owner } @@ -300,20 +289,56 @@ int Manager::onPgoodChanged(sd_bus_message* msg, return 0; } -void Manager::setCurrentTimeMode(const std::string& mode) +bool Manager::setCurrentTimeMode(const std::string& mode) { - log<level::INFO>("Time mode is changed", - entry("MODE=%s", mode.c_str())); - timeMode = convertToMode(mode); - utils::writeData(modeFile, mode); + auto newMode = convertToMode(mode); + if (newMode != timeMode) + { + log<level::INFO>("Time mode is changed", + entry("MODE=%s", mode.c_str())); + timeMode = newMode; + utils::writeData(modeFile, mode); + return true; + } + else + { + return false; + } +} + +bool Manager::setCurrentTimeOwner(const std::string& owner) +{ + auto newOwner = convertToOwner(owner); + if (newOwner != timeOwner) + { + log<level::INFO>("Time owner is changed", + entry("OWNER=%s", owner.c_str())); + timeOwner = newOwner; + utils::writeData(ownerFile, owner); + return true; + } + else + { + return false; + } +} + +void Manager::onTimeModeChanged(const std::string& mode) +{ + for (const auto listener : listeners) + { + listener->onModeChanged(timeMode); + } + // When time_mode is updated, update the NTP setting + updateNtpSetting(mode); } -void Manager::setCurrentTimeOwner(const std::string& owner) +void Manager::onTimeOwnerChanged() { - log<level::INFO>("Time owner is changed", - entry("OWNER=%s", owner.c_str())); - timeOwner = convertToOwner(owner); - utils::writeData(ownerFile, owner); + for (const auto& listener : listeners) + { + listener->onOwnerChanged(timeOwner); + } } std::string Manager::getSettings(const char* value) const diff --git a/manager.hpp b/manager.hpp index 7c00122..172105b 100644 --- a/manager.hpp +++ b/manager.hpp @@ -81,17 +81,37 @@ class Manager */ std::string getSettings(const char* setting) const; - /** @brief Set current time mode + /** @brief Set current time mode from the time mode string * * @param[in] mode - The string of time mode + * + * @return - true if the mode is updated + * false if it's the same as before */ - void setCurrentTimeMode(const std::string& mode); + bool setCurrentTimeMode(const std::string& mode); - /** @brief Set current time owner + /** @brief Set current time owner from the time owner string * * @param[in] owner - The string of time owner + * + * @return - true if the owner is updated + * false if it's the same as before + */ + bool setCurrentTimeOwner(const std::string& owner); + + /** @brief Called on time mode is changed + * + * Notify listeners that time mode is changed and update ntp setting + * + * @param[in] mode - The string of time mode + */ + void onTimeModeChanged(const std::string& mode); + + /** @brief Called on time owner is changed + * + * Notify listeners that time owner is changed */ - void setCurrentTimeOwner(const std::string& owner); + void onTimeOwnerChanged(); /** @brief Notified on settings property changed * diff --git a/test/TestManager.cpp b/test/TestManager.cpp index 1e4096e..bbaca96 100644 --- a/test/TestManager.cpp +++ b/test/TestManager.cpp @@ -3,6 +3,9 @@ #include "types.hpp" #include "manager.hpp" +#include "mocked_property_change_listener.hpp" + +using ::testing::_; namespace phosphor { @@ -14,12 +17,17 @@ class TestManager : public testing::Test public: sdbusplus::bus::bus bus; Manager manager; + MockPropertyChangeListner listener1; + MockPropertyChangeListner listener2; TestManager() : bus(sdbusplus::bus::new_default()), manager(bus) { - // Empty + // Add two mocked listeners so that we can test + // the behavior related to listeners + manager.addListener(&listener1); + manager.addListener(&listener2); } // Proxies for Manager's private members and functions @@ -104,28 +112,48 @@ TEST_F(TestManager, pgoodChange) EXPECT_FALSE(hostOn()); } -TEST_F(TestManager, propertyChange) +TEST_F(TestManager, propertyChanged) { // When host is off, property change will be notified to listners EXPECT_FALSE(hostOn()); + + // Check mocked listeners shall receive notifications on property changed + EXPECT_CALL(listener1, onModeChanged(Mode::MANUAL)).Times(1); + EXPECT_CALL(listener1, onOwnerChanged(Owner::HOST)).Times(1); + EXPECT_CALL(listener2, onModeChanged(Mode::MANUAL)).Times(1); + EXPECT_CALL(listener2, onOwnerChanged(Owner::HOST)).Times(1); + notifyPropertyChanged("time_mode", "MANUAL"); notifyPropertyChanged("time_owner", "HOST"); + EXPECT_EQ("", getRequestedMode()); EXPECT_EQ("", getRequestedOwner()); - // TODO: if gmock is ready, check mocked listners shall receive notifies - notifyPgoodChanged(true); // When host is on, property changes are saved as requested ones - notifyPropertyChanged("time_mode", "MANUAL"); - notifyPropertyChanged("time_owner", "HOST"); - EXPECT_EQ("MANUAL", getRequestedMode()); - EXPECT_EQ("HOST", getRequestedOwner()); + notifyPgoodChanged(true); + + // Check mocked listeners shall not receive notifications + EXPECT_CALL(listener1, onModeChanged(Mode::MANUAL)).Times(0); + EXPECT_CALL(listener1, onOwnerChanged(Owner::HOST)).Times(0); + EXPECT_CALL(listener2, onModeChanged(Mode::MANUAL)).Times(0); + EXPECT_CALL(listener2, onOwnerChanged(Owner::HOST)).Times(0); + + notifyPropertyChanged("time_mode", "NTP"); + notifyPropertyChanged("time_owner", "SPLIT"); + + EXPECT_EQ("NTP", getRequestedMode()); + EXPECT_EQ("SPLIT", getRequestedOwner()); // When host becomes off, the requested mode/owner shall be notified // to listners, and be cleared + EXPECT_CALL(listener1, onModeChanged(Mode::NTP)).Times(1); + EXPECT_CALL(listener1, onOwnerChanged(Owner::SPLIT)).Times(1); + EXPECT_CALL(listener2, onModeChanged(Mode::NTP)).Times(1); + EXPECT_CALL(listener2, onOwnerChanged(Owner::SPLIT)).Times(1); + notifyPgoodChanged(false); - // TODO: if gmock is ready, check mocked listners shall receive notifies + EXPECT_EQ("", getRequestedMode()); EXPECT_EQ("", getRequestedOwner()); @@ -135,6 +163,50 @@ TEST_F(TestManager, propertyChange) ASSERT_DEATH(notifyPropertyChanged("invalid property", "whatever"), ""); } +TEST_F(TestManager, propertyChangedAndChangedbackWhenHostOn) +{ + // Property is now MANUAL/HOST + notifyPropertyChanged("time_mode", "MANUAL"); + notifyPropertyChanged("time_owner", "HOST"); + + // Set host on + notifyPgoodChanged(true); + + // Check mocked listeners shall not receive notifications + EXPECT_CALL(listener1, onModeChanged(_)).Times(0); + EXPECT_CALL(listener1, onOwnerChanged(_)).Times(0); + EXPECT_CALL(listener2, onModeChanged(_)).Times(0); + EXPECT_CALL(listener2, onOwnerChanged(_)).Times(0); + + notifyPropertyChanged("time_mode", "NTP"); + notifyPropertyChanged("time_owner", "SPLIT"); + + // Saved as requested mode/owner + EXPECT_EQ("NTP", getRequestedMode()); + EXPECT_EQ("SPLIT", getRequestedOwner()); + + // Property changed back to MANUAL/HOST + notifyPropertyChanged("time_mode", "MANUAL"); + notifyPropertyChanged("time_owner", "HOST"); + + // Requested mode/owner shall be updated + EXPECT_EQ("MANUAL", getRequestedMode()); + EXPECT_EQ("HOST", getRequestedOwner()); + + // Because the latest mode/owner is the same as when host is off, + // The listeners shall not be notified, and requested mode/owner + // shall be cleared + EXPECT_CALL(listener1, onModeChanged(_)).Times(0); + EXPECT_CALL(listener1, onOwnerChanged(_)).Times(0); + EXPECT_CALL(listener2, onModeChanged(_)).Times(0); + EXPECT_CALL(listener2, onOwnerChanged(_)).Times(0); + + notifyPgoodChanged(false); + + EXPECT_EQ("", getRequestedMode()); + EXPECT_EQ("", getRequestedOwner()); +} + // TODO: if gmock is ready, add case to test // updateNtpSetting() and updateNetworkSetting() diff --git a/test/mocked_property_change_listener.hpp b/test/mocked_property_change_listener.hpp new file mode 100644 index 0000000..d581dd3 --- /dev/null +++ b/test/mocked_property_change_listener.hpp @@ -0,0 +1,17 @@ +#pragma once +#include <gmock/gmock.h> +#include "property_change_listener.hpp" + +namespace phosphor { +namespace time { + +class MockPropertyChangeListner : public PropertyChangeListner { + public: + MOCK_METHOD1(onModeChanged, + void(Mode mode)); + MOCK_METHOD1(onOwnerChanged, + void(Owner owner)); +}; + +} // namespace time +} // namespace phosphor |