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
SetUp()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
TEST_F(HealthMetricTest,TestMetricUnmockedObjectAddRemove)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
TEST_F(HealthMetricTest,TestMetricThresholdChange)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