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 = std::string(PathIntf::value) + "/bmc/" + 32 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.collectionFreq = ConfigIntf::HealthMetric::defaults::frequency; 40 config.windowSize = 1; 41 config.thresholds = { 42 {{ThresholdIntf::Type::Critical, ThresholdIntf::Bound::Upper}, 43 {.value = 90.0, .log = true, .target = ""}}, 44 {{ThresholdIntf::Type::Warning, ThresholdIntf::Bound::Upper}, 45 {.value = 80.0, .log = false, .target = ""}}}; 46 config.path = ""; 47 } 48 }; 49 50 TEST_F(HealthMetricTest, TestMetricUnmockedObjectAddRemove) 51 { 52 sdbusplus::bus_t unmockedBus = sdbusplus::bus::new_bus(); 53 unmockedBus.request_name(busName); 54 auto metric = std::make_unique<HealthMetric>(unmockedBus, Type::cpu, config, 55 paths_t()); 56 } 57 58 TEST_F(HealthMetricTest, TestMetricThresholdChange) 59 { 60 sdbusplus::server::manager_t objManager(bus, objPath.c_str()); 61 bus.request_name(busName); 62 const auto thresholdProperties = std::set<std::string>{"Value", "Asserted"}; 63 64 EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv( 65 IsNull(), StrEq(objPath), 66 StrEq(ValueIntf::interface), NotNull())) 67 .WillRepeatedly(Invoke( 68 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path, 69 [[maybe_unused]] const char* interface, const char** names) { 70 EXPECT_THAT(properties, testing::Contains(names[0])); 71 return 0; 72 })); 73 EXPECT_CALL(sdbusMock, sd_bus_emit_properties_changed_strv( 74 IsNull(), StrEq(objPath), 75 StrEq(ThresholdIntf::interface), NotNull())) 76 .WillRepeatedly(Invoke( 77 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path, 78 [[maybe_unused]] const char* interface, const char** names) { 79 EXPECT_THAT(thresholdProperties, testing::Contains(names[0])); 80 return 0; 81 })); 82 EXPECT_CALL(sdbusMock, 83 sd_bus_message_new_signal(_, _, StrEq(objPath), 84 StrEq(ThresholdIntf::interface), 85 StrEq("AssertionChanged"))) 86 .Times(4); 87 88 auto metric = std::make_unique<HealthMetric>(bus, Type::cpu, config, 89 paths_t()); 90 // Exceed the critical threshold 91 metric->update(MValue(1200, 95.0)); 92 // Go below critical threshold but above warning threshold 93 metric->update(MValue(1200, 85.0)); 94 // Go below warning threshold 95 metric->update(MValue(1200, 75.0)); 96 } 97