xref: /openbmc/telemetry/tests/src/test_sensor.cpp (revision d2238194)
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     static std::unique_ptr<stubs::DbusSensorObject> makeSensorObject()
38     {
39         return std::make_unique<stubs::DbusSensorObject>(
40             DbusEnvironment::getIoc(), DbusEnvironment::getBus(),
41             DbusEnvironment::getObjServer());
42     }
43 
44     std::unique_ptr<stubs::DbusSensorObject> sensorObject = makeSensorObject();
45 
46     SensorCache sensorCache;
47     uint64_t timestamp = std::time(0);
48     std::shared_ptr<Sensor> sut = sensorCache.makeSensor<Sensor>(
49         DbusEnvironment::serviceName(), sensorObject->path(),
50         DbusEnvironment::getIoc(), DbusEnvironment::getBus());
51     std::shared_ptr<SensorListenerMock> listenerMock =
52         std::make_shared<StrictMock<SensorListenerMock>>();
53     std::shared_ptr<SensorListenerMock> listenerMock2 =
54         std::make_shared<StrictMock<SensorListenerMock>>();
55     MockFunction<void()> checkPoint;
56 };
57 
58 TEST_F(TestSensor, createsCorretlyViaSensorCache)
59 {
60     ASSERT_THAT(sut->id(),
61                 Eq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
62                               sensorObject->path())));
63 }
64 
65 TEST_F(TestSensor, notifiesWithValueAfterRegister)
66 {
67     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
68         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
69 
70     registerForUpdates(listenerMock);
71 
72     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
73 }
74 
75 TEST_F(TestSensor, notifiesOnceWithValueAfterRegister)
76 {
77     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
78         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
79     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
80         .WillOnce(
81             InvokeWithoutArgs(DbusEnvironment::setPromise("async_read2")));
82 
83     DbusEnvironment::synchronizedPost([this] {
84         sut->registerForUpdates(listenerMock);
85         sut->registerForUpdates(listenerMock2);
86     });
87 
88     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
89     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
90 }
91 
92 class TestSensorNotification : public TestSensor
93 {
94   public:
95     void SetUp() override
96     {
97         EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
98             .WillOnce(
99                 InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
100 
101         registerForUpdates(listenerMock);
102 
103         ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
104     }
105 
106     std::shared_ptr<SensorListenerMock> listenerMock2 =
107         std::make_shared<StrictMock<SensorListenerMock>>();
108 };
109 
110 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
111 {
112     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
113         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
114 
115     sensorObject->setValue(42.7);
116 
117     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
118 }
119 
120 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenNoChangeOccurs)
121 {
122     InSequence seq;
123 
124     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7));
125     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp)))
126         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
127 
128     sensorObject->setValue(42.7);
129     sensorObject->setValue(42.7);
130 
131     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
132 }
133 
134 TEST_F(TestSensorNotification, doesntNotifyExpiredListener)
135 {
136     InSequence seq;
137     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
138     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
139         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
140 
141     registerForUpdates(listenerMock2);
142     listenerMock = nullptr;
143 
144     sensorObject->setValue(42.7);
145 
146     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
147 }
148 
149 TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
150 {
151     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
152 
153     registerForUpdates(listenerMock2);
154 }
155 
156 TEST_F(TestSensorNotification,
157        dbusSensorIsAddedToSystemAfterSensorIsCreatedThenValueIsUpdated)
158 {
159     InSequence seq;
160 
161     EXPECT_CALL(*listenerMock,
162                 sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(42.7)))
163         .WillOnce(
164             InvokeWithoutArgs(DbusEnvironment::setPromise("notify-change")));
165     EXPECT_CALL(checkPoint, Call());
166     EXPECT_CALL(*listenerMock,
167                 sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(0.)))
168         .WillOnce(
169             InvokeWithoutArgs(DbusEnvironment::setPromise("notify-create")));
170 
171     sensorObject->setValue(42.7);
172     DbusEnvironment::waitForFuture("notify-change");
173 
174     checkPoint.Call();
175 
176     sensorObject = nullptr;
177     sensorObject = makeSensorObject();
178     DbusEnvironment::waitForFuture("notify-create");
179 }
180