1 #include "health_metric.hpp" 2 3 #include <sdbusplus/test/sdbus_mock.hpp> 4 #include <xyz/openbmc_project/Metric/Value/server.hpp> 5 6 #include <gmock/gmock.h> 7 #include <gtest/gtest.h> 8 9 namespace ConfigIntf = phosphor::health::metric::config; 10 using PathIntf = 11 sdbusplus::server::xyz::openbmc_project::metric::Value::namespace_path; 12 using namespace phosphor::health::metric; 13 using namespace phosphor::health::utils; 14 15 using ::testing::_; 16 using ::testing::InSequence; 17 using ::testing::Invoke; 18 using ::testing::IsNull; 19 using ::testing::NotNull; 20 using ::testing::Pair; 21 using ::testing::StrEq; 22 23 class HealthMetricTest : public ::testing::Test 24 { 25 public: 26 sdbusplus::SdBusMock sdbusMock; 27 sdbusplus::bus_t bus = sdbusplus::get_mocked_new(&sdbusMock); 28 static constexpr auto busName = "xyz.openbmc_project.test.HealthMon"; 29 const std::set<std::string> properties = {"Value", "MaxValue", "MinValue", 30 "Unit"}; 31 const std::string objPath = 32 std::string(PathIntf::value) + "/bmc/" + PathIntf::kernel_cpu; 33 ConfigIntf::HealthMetric config; 34 35 void SetUp() override 36 { 37 config.name = "CPU_Kernel"; 38 config.subType = SubType::cpuKernel; 39 config.windowSize = 1; 40 config.thresholds = { 41 {{ThresholdIntf::Type::Critical, ThresholdIntf::Bound::Upper}, 42 {.value = 90.0, .log = true, .target = ""}}, 43 {{ThresholdIntf::Type::Warning, ThresholdIntf::Bound::Upper}, 44 {.value = 80.0, .log = false, .target = ""}}}; 45 config.path = ""; 46 } 47 }; 48 49 TEST_F(HealthMetricTest, TestMetricUnmockedObjectAddRemove) 50 { 51 sdbusplus::bus_t unmockedBus = sdbusplus::bus::new_bus(); 52 unmockedBus.request_name(busName); 53 auto metric = std::make_unique<HealthMetric>(unmockedBus, Type::cpu, config, 54 paths_t()); 55 } 56 57 TEST_F(HealthMetricTest, TestMetricThresholdChange) 58 { 59 sdbusplus::server::manager_t objManager(bus, objPath.c_str()); 60 bus.request_name(busName); 61 const auto thresholdProperties = std::set<std::string>{"Value", "Asserted"}; 62 63 EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv( 64 IsNull(), StrEq(objPath), 65 StrEq(ValueIntf::interface), NotNull())) 66 .WillRepeatedly(Invoke( 67 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path, 68 [[maybe_unused]] const char* interface, const char** names) { 69 EXPECT_THAT(properties, testing::Contains(names[0])); 70 return 0; 71 })); 72 EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv( 73 IsNull(), StrEq(objPath), 74 StrEq(ThresholdIntf::interface), NotNull())) 75 .WillRepeatedly(Invoke( 76 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path, 77 [[maybe_unused]] const char* interface, const char** names) { 78 EXPECT_THAT(thresholdProperties, testing::Contains(names[0])); 79 return 0; 80 })); 81 EXPECT_CALL(sdbusMock, 82 sd_bus_message_new_signal(_, _, StrEq(objPath), 83 StrEq(ThresholdIntf::interface), 84 StrEq("AssertionChanged"))) 85 .Times(4); 86 87 auto metric = 88 std::make_unique<HealthMetric>(bus, Type::cpu, config, paths_t()); 89 // Exceed the critical threshold 90 metric->update(MValue(1351, 1500)); 91 // Go below critical threshold but above warning threshold 92 metric->update(MValue(1399, 1500)); 93 // Go below warning threshold 94 metric->update(MValue(1199, 1500)); 95 } 96