xref: /openbmc/telemetry/tests/src/test_sensor.cpp (revision 7e098e93ef0974739459d296f99ddfab54722c23)
1 #include "dbus_environment.hpp"
2 #include "helpers.hpp"
3 #include "mocks/sensor_listener_mock.hpp"
4 #include "sensor.hpp"
5 #include "sensor_cache.hpp"
6 #include "stubs/dbus_sensor_object.hpp"
7 
8 #include <sdbusplus/asio/property.hpp>
9 
10 #include <thread>
11 
12 #include <gmock/gmock.h>
13 
14 using namespace testing;
15 using namespace std::chrono_literals;
16 
17 class TestSensor : public Test
18 {
19   public:
20     void SetUp() override
21     {
22         sensorObject->setValue(42.7);
23     }
24 
25     void TearDown() override
26     {
27         DbusEnvironment::synchronizeIoc();
28     }
29 
30     void
31         registerForUpdates(std::shared_ptr<interfaces::SensorListener> listener)
32     {
33         sut->registerForUpdates(listener);
34         DbusEnvironment::synchronizeIoc();
35     }
36 
37     void unregisterFromUpdates(
38         std::shared_ptr<interfaces::SensorListener> listener)
39     {
40         sut->unregisterFromUpdates(listener);
41         DbusEnvironment::synchronizeIoc();
42     }
43 
44     static std::unique_ptr<stubs::DbusSensorObject> makeSensorObject()
45     {
46         return std::make_unique<stubs::DbusSensorObject>(
47             DbusEnvironment::getIoc(), DbusEnvironment::getBus(),
48             DbusEnvironment::getObjServer());
49     }
50 
51     std::unique_ptr<stubs::DbusSensorObject> sensorObject = makeSensorObject();
52 
53     SensorCache sensorCache;
54     uint64_t timestamp = std::time(0);
55     std::shared_ptr<Sensor> sut = sensorCache.makeSensor<Sensor>(
56         DbusEnvironment::serviceName(), sensorObject->path(),
57         DbusEnvironment::getIoc(), DbusEnvironment::getBus());
58     std::shared_ptr<SensorListenerMock> listenerMock =
59         std::make_shared<StrictMock<SensorListenerMock>>();
60     std::shared_ptr<SensorListenerMock> listenerMock2 =
61         std::make_shared<StrictMock<SensorListenerMock>>();
62     MockFunction<void()> checkPoint;
63 };
64 
65 TEST_F(TestSensor, createsCorretlyViaSensorCache)
66 {
67     ASSERT_THAT(sut->id(),
68                 Eq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
69                               sensorObject->path())));
70 }
71 
72 TEST_F(TestSensor, notifiesWithValueAfterRegister)
73 {
74     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
75         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
76 
77     registerForUpdates(listenerMock);
78 
79     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
80 }
81 
82 TEST_F(TestSensor, notifiesOnceWithValueAfterRegister)
83 {
84     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
85         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
86     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
87         .WillOnce(
88             InvokeWithoutArgs(DbusEnvironment::setPromise("async_read2")));
89 
90     DbusEnvironment::synchronizedPost([this] {
91         sut->registerForUpdates(listenerMock);
92         sut->registerForUpdates(listenerMock2);
93     });
94 
95     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
96     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
97 }
98 
99 class TestSensorNotification : public TestSensor
100 {
101   public:
102     void SetUp() override
103     {
104         EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
105             .WillOnce(
106                 InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
107 
108         registerForUpdates(listenerMock);
109 
110         ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
111     }
112 
113     std::shared_ptr<SensorListenerMock> listenerMock2 =
114         std::make_shared<StrictMock<SensorListenerMock>>();
115 };
116 
117 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
118 {
119     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
120         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
121 
122     sensorObject->setValue(42.7);
123 
124     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
125 }
126 
127 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenNoChangeOccurs)
128 {
129     InSequence seq;
130 
131     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7));
132     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp)))
133         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
134 
135     sensorObject->setValue(42.7);
136     sensorObject->setValue(42.7);
137 
138     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
139 }
140 
141 TEST_F(TestSensorNotification, doesntNotifyExpiredListener)
142 {
143     InSequence seq;
144     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
145     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
146         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
147 
148     registerForUpdates(listenerMock2);
149     listenerMock = nullptr;
150 
151     sensorObject->setValue(42.7);
152 
153     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
154 }
155 
156 TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
157 {
158     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
159 
160     registerForUpdates(listenerMock2);
161 }
162 
163 TEST_F(TestSensorNotification, notNotifiesWithValueWhenUnregistered)
164 {
165     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
166     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
167         .Times(0);
168     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
169         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
170 
171     registerForUpdates(listenerMock2);
172     unregisterFromUpdates(listenerMock);
173 
174     sensorObject->setValue(42.7);
175 
176     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
177 }
178 
179 TEST_F(TestSensorNotification,
180        dbusSensorIsAddedToSystemAfterSensorIsCreatedThenValueIsUpdated)
181 {
182     InSequence seq;
183 
184     EXPECT_CALL(*listenerMock,
185                 sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(42.7)))
186         .WillOnce(
187             InvokeWithoutArgs(DbusEnvironment::setPromise("notify-change")));
188     EXPECT_CALL(checkPoint, Call());
189     EXPECT_CALL(*listenerMock,
190                 sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(0.)))
191         .WillOnce(
192             InvokeWithoutArgs(DbusEnvironment::setPromise("notify-create")));
193 
194     sensorObject->setValue(42.7);
195     DbusEnvironment::waitForFuture("notify-change");
196 
197     checkPoint.Call();
198 
199     sensorObject = nullptr;
200     sensorObject = makeSensorObject();
201     DbusEnvironment::waitForFuture("notify-create");
202 }
203