add health_metric implementation
Add the interface and implementation for the health_metric to be used
in the rewrite for phosphor-health-monitor.
This change is in relation to following design and D-Bus interface
update -
https://gerrit.openbmc.org/c/openbmc/docs/+/64917
https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/64914
gtest added for UT.
Change-Id: Iffcc52f9dff712890377b1222fd7e7d5d6661eaf
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
diff --git a/test/test_health_metric.cpp b/test/test_health_metric.cpp
new file mode 100644
index 0000000..9e9f1f5
--- /dev/null
+++ b/test/test_health_metric.cpp
@@ -0,0 +1,96 @@
+#include "health_metric.hpp"
+
+#include <sdbusplus/test/sdbus_mock.hpp>
+#include <xyz/openbmc_project/Metric/Value/server.hpp>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace ConfigIntf = phosphor::health::metric::config;
+using PathIntf =
+ sdbusplus::server::xyz::openbmc_project::metric::Value::namespace_path;
+using namespace phosphor::health::metric;
+using namespace phosphor::health::utils;
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::Pair;
+using ::testing::StrEq;
+
+class HealthMetricTest : public ::testing::Test
+{
+ public:
+ sdbusplus::SdBusMock sdbusMock;
+ sdbusplus::bus::bus bus = sdbusplus::get_mocked_new(&sdbusMock);
+ static constexpr auto busName = "xyz.openbmc_project.test.HealthMon";
+ const std::set<std::string> properties = {"Value", "MaxValue", "MinValue",
+ "Unit"};
+ const std::string objPath = std::string(PathIntf::value) + "/bmc/" +
+ PathIntf::kernel_cpu;
+ ConfigIntf::HealthMetric config;
+
+ void SetUp() override
+ {
+ config.name = "CPU_Kernel";
+ config.subType = SubType::cpuKernel;
+ config.collectionFreq = ConfigIntf::HealthMetric::defaults::frequency;
+ config.windowSize = 1;
+ config.thresholds = {
+ {{ThresholdIntf::Type::Critical, ThresholdIntf::Bound::Upper},
+ {.value = 90.0, .log = true, .target = ""}},
+ {{ThresholdIntf::Type::Warning, ThresholdIntf::Bound::Upper},
+ {.value = 80.0, .log = false, .target = ""}}};
+ config.path = "";
+ }
+};
+
+TEST_F(HealthMetricTest, TestMetricUnmockedObjectAddRemove)
+{
+ sdbusplus::bus::bus unmockedBus = sdbusplus::bus::new_bus();
+ unmockedBus.request_name(busName);
+ auto metric = std::make_unique<HealthMetric>(unmockedBus, Type::cpu, config,
+ paths_t());
+}
+
+TEST_F(HealthMetricTest, TestMetricThresholdChange)
+{
+ sdbusplus::server::manager_t objManager(bus, objPath.c_str());
+ bus.request_name(busName);
+ const auto thresholdProperties = std::set<std::string>{"Value", "Asserted"};
+
+ EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv(
+ IsNull(), StrEq(objPath),
+ StrEq(ValueIntf::interface), NotNull()))
+ .WillRepeatedly(Invoke(
+ [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
+ [[maybe_unused]] const char* interface, const char** names) {
+ EXPECT_THAT(properties, testing::Contains(names[0]));
+ return 0;
+ }));
+ EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv(
+ IsNull(), StrEq(objPath),
+ StrEq(ThresholdIntf::interface), NotNull()))
+ .WillRepeatedly(Invoke(
+ [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
+ [[maybe_unused]] const char* interface, const char** names) {
+ EXPECT_THAT(thresholdProperties, testing::Contains(names[0]));
+ return 0;
+ }));
+ EXPECT_CALL(sdbusMock,
+ sd_bus_message_new_signal(_, _, StrEq(objPath),
+ StrEq(ThresholdIntf::interface),
+ StrEq("AssertionChanged")))
+ .Times(4);
+
+ auto metric = std::make_unique<HealthMetric>(bus, Type::cpu, config,
+ paths_t());
+ // Exceed the critical threshold
+ metric->update(MValue(1200, 95.0));
+ // Go below critical threshold but above warning threshold
+ metric->update(MValue(1200, 85.0));
+ // Go below warning threshold
+ metric->update(MValue(1200, 75.0));
+}