blob: bb1512af96c8276b8fa94a10e7594f7fda0c3911 [file] [log] [blame]
Jagpal Singh Gill79434b52023-12-10 15:33:05 -08001#include "health_metric_collection.hpp"
2
3#include <sdbusplus/test/sdbus_mock.hpp>
4#include <xyz/openbmc_project/Metric/Value/server.hpp>
5
6#include <gtest/gtest.h>
7
8namespace ConfigIntf = phosphor::health::metric::config;
9namespace MetricIntf = phosphor::health::metric;
10namespace CollectionIntf = phosphor::health::metric::collection;
11
12using PathInterface =
13 sdbusplus::common::xyz::openbmc_project::metric::Value::namespace_path;
14using ThresholdIntf =
15 sdbusplus::server::xyz::openbmc_project::common::Threshold;
16using ::testing::Invoke;
17using ::testing::IsNull;
18using ::testing::NotNull;
19using ::testing::StrEq;
20
21class HealthMetricCollectionTest : public ::testing::Test
22{
23 public:
24 sdbusplus::SdBusMock sdbusMock;
Patrick Williamsfbb835b2024-02-22 02:34:39 -060025 sdbusplus::bus_t bus = sdbusplus::get_mocked_new(&sdbusMock);
Jagpal Singh Gill79434b52023-12-10 15:33:05 -080026
27 static constexpr auto busName = "xyz.openbmc_project.test.HealthMon";
28 static constexpr auto objPath = "/xyz/openbmc_project/sdbusplus/test";
29 const std::string valueInterface =
30 sdbusplus::common::xyz::openbmc_project::metric::Value::interface;
31 const std::string thresholdInterface =
32 sdbusplus::common::xyz::openbmc_project::common::Threshold::interface;
33 ConfigIntf::HealthMetric::map_t configs;
34
35 void SetUp() override
36 {
37 sdbusplus::server::manager_t objManager(bus, objPath);
38 bus.request_name(busName);
39
40 configs = ConfigIntf::getHealthMetricConfigs();
41 EXPECT_THAT(configs.size(), testing::Ge(1));
42 // Update the health metric window size to 1 and path for test purposes
43 for (auto& [key, values] : configs)
44 {
45 for (auto& config : values)
46 {
47 config.windowSize = 1;
48 if (key == MetricIntf::Type::storage &&
49 config.subType == MetricIntf::SubType::storageReadWrite)
50 {
51 config.path = "/tmp";
52 }
53 }
54 }
55 }
56
57 void updateThreshold(double value)
58 {
59 for (auto& [key, values] : configs)
60 {
61 for (auto& config : values)
62 {
63 for (auto& threshold : config.thresholds)
64 {
65 threshold.second.value = value;
66 }
67 }
68 }
69 }
70
71 void createCollection()
72 {
73 std::map<MetricIntf::Type,
74 std::unique_ptr<CollectionIntf::HealthMetricCollection>>
75 collections;
76 MetricIntf::paths_t bmcPaths = {};
77 for (const auto& [type, collectionConfig] : configs)
78 {
79 collections[type] =
80 std::make_unique<CollectionIntf::HealthMetricCollection>(
81 bus, type, collectionConfig, bmcPaths);
82 collections[type]->read();
83 }
84 }
85};
86
87TEST_F(HealthMetricCollectionTest, TestCreation)
88{
89 // Change threshold value to 100 to avoid threshold assertion
90 updateThreshold(100);
91
92 EXPECT_CALL(sdbusMock,
93 sd_bus_emit_properties_changed_strv(
94 IsNull(), NotNull(), StrEq(valueInterface), NotNull()))
95 .WillRepeatedly(Invoke(
96 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
97 [[maybe_unused]] const char* interface, const char** names) {
98 // Test no signal generation for metric init properties
99 const std::set<std::string> metricInitProperties = {"MaxValue",
100 "MinValue", "Unit"};
101 EXPECT_THAT(metricInitProperties,
102 testing::Not(testing::Contains(names[0])));
103 // Test signal generated for Value property set
104 const std::set<std::string> metricSetProperties = {"Value"};
105 EXPECT_THAT(metricSetProperties, testing::Contains(names[0]));
106 return 0;
107 }));
108
109 EXPECT_CALL(sdbusMock,
110 sd_bus_emit_properties_changed_strv(
111 IsNull(), NotNull(), StrEq(thresholdInterface), NotNull()))
112 .WillRepeatedly(Invoke(
113 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
114 [[maybe_unused]] const char* interface, const char** names) {
115 // Test no signal generation for threshold init properties
116 const std::set<std::string> thresholdProperties = {"Value", "Asserted"};
117 EXPECT_THAT(thresholdProperties,
118 testing::Not(testing::Contains(names[0])));
119 return 0;
120 }));
121
122 createCollection();
123}
124
125TEST_F(HealthMetricCollectionTest, TestThresholdAsserted)
126{
127 // Change threshold value to 0 to trigger threshold assertion
128 updateThreshold(0);
129
130 // Test metric value property change
131 EXPECT_CALL(sdbusMock,
132 sd_bus_emit_properties_changed_strv(
133 IsNull(), NotNull(), StrEq(valueInterface), NotNull()))
134 .WillRepeatedly(Invoke(
135 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
136 [[maybe_unused]] const char* interface, const char** names) {
137 EXPECT_THAT("Value", StrEq(names[0]));
138 return 0;
139 }));
140
141 // Test threshold asserted property change
142 EXPECT_CALL(sdbusMock,
143 sd_bus_emit_properties_changed_strv(
144 IsNull(), NotNull(), StrEq(thresholdInterface), NotNull()))
145 .WillRepeatedly(Invoke(
146 [&]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path,
147 [[maybe_unused]] const char* interface, const char** names) {
148 EXPECT_THAT("Asserted", StrEq(names[0]));
149 return 0;
150 }));
151
152 // Test AssertionChanged signal generation
153 EXPECT_CALL(sdbusMock,
154 sd_bus_message_new_signal(IsNull(), NotNull(), NotNull(),
155 StrEq(thresholdInterface),
156 StrEq("AssertionChanged")))
157 .Times(11);
158
159 createCollection();
160}