xref: /openbmc/telemetry/tests/src/test_sensor.cpp (revision b5645947)
1 #include "dbus_environment.hpp"
2 #include "mocks/sensor_listener_mock.hpp"
3 #include "sensor.hpp"
4 #include "sensor_cache.hpp"
5 #include "stubs/dbus_sensor_object.hpp"
6 #include "utils/sensor_id_eq.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         DbusEnvironment::synchronizedPost(
34             [this, listener] { sut->registerForUpdates(listener); });
35     }
36 
37     std::chrono::milliseconds notifiesInGivenIntervalAfterSchedule(
38         std::chrono::milliseconds interval);
39 
40     stubs::DbusSensorObject sensorObject{DbusEnvironment::getIoc(),
41                                          DbusEnvironment::getBus(),
42                                          DbusEnvironment::getObjServer()};
43 
44     SensorCache sensorCache;
45     uint64_t timestamp = std::time(0);
46     std::shared_ptr<Sensor> sut = sensorCache.makeSensor<Sensor>(
47         DbusEnvironment::serviceName(), sensorObject.path(),
48         DbusEnvironment::getIoc(), DbusEnvironment::getBus());
49     std::shared_ptr<SensorListenerMock> listenerMock =
50         std::make_shared<StrictMock<SensorListenerMock>>();
51     std::shared_ptr<SensorListenerMock> listenerMock2 =
52         std::make_shared<StrictMock<SensorListenerMock>>();
53 };
54 
55 TEST_F(TestSensor, createsCorretlyViaSensorCache)
56 {
57     ASSERT_THAT(sut->id(),
58                 sensorIdEq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
59                                       sensorObject.path())));
60 }
61 
62 TEST_F(TestSensor, notifiesWithValueAfterRegister)
63 {
64     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
65         .WillOnce(Invoke(DbusEnvironment::setPromise("async_read")));
66 
67     registerForUpdates(listenerMock);
68 
69     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
70 }
71 
72 TEST_F(TestSensor, notifiesOnceWithValueAfterRegister)
73 {
74     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
75         .WillOnce(Invoke(DbusEnvironment::setPromise("async_read")));
76     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
77         .WillOnce(Invoke(DbusEnvironment::setPromise("async_read2")));
78 
79     DbusEnvironment::synchronizedPost([this] {
80         sut->registerForUpdates(listenerMock);
81         sut->registerForUpdates(listenerMock2);
82     });
83 
84     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
85     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
86 }
87 
88 class TestSensorNotification : public TestSensor
89 {
90   public:
91     void SetUp() override
92     {
93         EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
94             .WillOnce(Invoke(DbusEnvironment::setPromise("async_read")));
95 
96         registerForUpdates(listenerMock);
97 
98         ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
99     }
100 
101     std::shared_ptr<SensorListenerMock> listenerMock2 =
102         std::make_shared<StrictMock<SensorListenerMock>>();
103 };
104 
105 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
106 {
107     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
108         .WillOnce(Invoke(DbusEnvironment::setPromise("notify")));
109 
110     sensorObject.setValue(42.7);
111 
112     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
113 }
114 
115 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenNoChangeOccurs)
116 {
117     Sequence seq;
118 
119     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
120         .InSequence(seq);
121     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp)))
122         .InSequence(seq)
123         .WillOnce(Invoke(DbusEnvironment::setPromise("notify")));
124 
125     sensorObject.setValue(42.7);
126     sensorObject.setValue(42.7);
127 
128     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
129 }
130 
131 TEST_F(TestSensorNotification, doesntNotifyExpiredListener)
132 {
133     Sequence seq;
134     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
135         .InSequence(seq);
136     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
137         .InSequence(seq)
138         .WillOnce(Invoke(DbusEnvironment::setPromise("notify")));
139 
140     registerForUpdates(listenerMock2);
141     listenerMock = nullptr;
142 
143     sensorObject.setValue(42.7);
144 
145     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
146 }
147 
148 TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
149 {
150     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
151 
152     registerForUpdates(listenerMock2);
153 }
154