xref: /openbmc/telemetry/tests/src/test_metric.cpp (revision 5ade2b1d0ccb71a3de23396dea77c375bedc0362)
1 #include "helpers/metric_value_helpers.hpp"
2 #include "interfaces/sensor.hpp"
3 #include "metric.hpp"
4 #include "mocks/sensor_mock.hpp"
5 #include "printers.hpp"
6 #include "utils/conv_container.hpp"
7 
8 #include <gmock/gmock.h>
9 
10 using namespace testing;
11 
12 using Timestamp = uint64_t;
13 
14 class TestMetric : public Test
15 {
16   public:
17     std::vector<std::shared_ptr<SensorMock>> sensorMocks = {
18         std::make_shared<NiceMock<SensorMock>>(),
19         std::make_shared<NiceMock<SensorMock>>(),
20         std::make_shared<NiceMock<SensorMock>>()};
21 
22     std::shared_ptr<Metric> sut = std::make_shared<Metric>(
23         utils::convContainer<std::shared_ptr<interfaces::Sensor>>(sensorMocks),
24         "op", "id", "metadata");
25 };
26 
27 TEST_F(TestMetric, subscribesForSensorDuringInitialization)
28 {
29     for (auto& sensor : sensorMocks)
30     {
31         EXPECT_CALL(*sensor,
32                     registerForUpdates(Truly([sut = sut.get()](const auto& a0) {
33                         return a0.lock().get() == sut;
34                     })));
35     }
36 
37     sut->initialize();
38 }
39 
40 TEST_F(TestMetric, containsNoReadingsWhenNotInitialized)
41 {
42     ASSERT_THAT(sut->getReadings(), ElementsAre());
43 }
44 
45 TEST_F(TestMetric, containsEmptyReadingsAfterInitialize)
46 {
47     sut->initialize();
48 
49     ASSERT_THAT(sut->getReadings(),
50                 ElementsAre(MetricValue{"id", "metadata", 0., 0u},
51                             MetricValue{"id", "metadata", 0., 0u},
52                             MetricValue{"id", "metadata", 0., 0u}));
53 }
54 
55 TEST_F(TestMetric, throwsWhenUpdateIsPerformedWhenNotInitialized)
56 {
57     EXPECT_THROW(sut->sensorUpdated(*sensorMocks[0], Timestamp{10}),
58                  std::out_of_range);
59     EXPECT_THROW(sut->sensorUpdated(*sensorMocks[1], Timestamp{10}, 20.0),
60                  std::out_of_range);
61 }
62 
63 TEST_F(TestMetric, updatesMetricValuesOnSensorUpdate)
64 {
65     sut->initialize();
66 
67     sut->sensorUpdated(*sensorMocks[2], Timestamp{18}, 31.0);
68     sut->sensorUpdated(*sensorMocks[0], Timestamp{21});
69 
70     ASSERT_THAT(sut->getReadings(),
71                 ElementsAre(MetricValue{"id", "metadata", 0., 21u},
72                             MetricValue{"id", "metadata", 0., 0u},
73                             MetricValue{"id", "metadata", 31., 18u}));
74 }
75 
76 TEST_F(TestMetric, throwsWhenUpdateIsPerformedOnUnknownSensor)
77 {
78     sut->initialize();
79 
80     auto sensor = std::make_shared<StrictMock<SensorMock>>();
81     EXPECT_THROW(sut->sensorUpdated(*sensor, Timestamp{10}), std::out_of_range);
82     EXPECT_THROW(sut->sensorUpdated(*sensor, Timestamp{10}, 20.0),
83                  std::out_of_range);
84 }
85 
86 TEST_F(TestMetric, containsIdInJsonDump)
87 {
88     ASSERT_THAT(sut->to_json().at("id"), Eq(nlohmann::json("id")));
89 }
90 
91 TEST_F(TestMetric, containsOpInJsonDump)
92 {
93     ASSERT_THAT(sut->to_json().at("operationType"), Eq(nlohmann::json("op")));
94 }
95 
96 TEST_F(TestMetric, containsMetadataInJsonDump)
97 {
98     ASSERT_THAT(sut->to_json().at("metricMetadata"),
99                 Eq(nlohmann::json("metadata")));
100 }
101 
102 TEST_F(TestMetric, containsSensorPathsInJsonDump)
103 {
104     for (size_t i = 0; i < sensorMocks.size(); ++i)
105     {
106         const auto no = std::to_string(i);
107         ON_CALL(*sensorMocks[i], id())
108             .WillByDefault(
109                 Return(SensorMock::makeId("service" + no, "path" + no)));
110     }
111 
112     ASSERT_THAT(sut->to_json().at("sensorPaths"),
113                 Eq(nlohmann::json(
114                     {"service0:path0", "service1:path1", "service2:path2"})));
115 }
116