xref: /openbmc/telemetry/tests/src/test_sensor.cpp (revision e2362796)
1 #include "dbus_environment.hpp"
2 #include "mocks/sensor_listener_mock.hpp"
3 #include "printers.hpp"
4 #include "sensor.hpp"
5 #include "sensor_cache.hpp"
6 #include "stubs/dbus_sensor_object.hpp"
7 #include "utils/sensor_id_eq.hpp"
8 
9 #include <sdbusplus/asio/property.hpp>
10 
11 #include <thread>
12 
13 #include <gmock/gmock.h>
14 
15 using namespace testing;
16 using namespace std::chrono_literals;
17 
18 class TestSensor : public Test
19 {
20   public:
21     void SetUp() override
22     {
23         sensorObject.setValue(42.7);
24     }
25 
26     void TearDown() override
27     {
28         DbusEnvironment::synchronizeIoc();
29     }
30 
31     void
32         registerForUpdates(std::shared_ptr<interfaces::SensorListener> listener)
33     {
34         DbusEnvironment::synchronizedPost(
35             [this, listener] { sut->registerForUpdates(listener); });
36     }
37 
38     std::chrono::milliseconds notifiesInGivenIntervalAfterSchedule(
39         std::chrono::milliseconds interval);
40 
41     stubs::DbusSensorObject sensorObject{DbusEnvironment::getIoc(),
42                                          DbusEnvironment::getBus(),
43                                          DbusEnvironment::getObjServer()};
44 
45     SensorCache sensorCache;
46     uint64_t timestamp = std::time(0);
47     std::shared_ptr<Sensor> sut = sensorCache.makeSensor<Sensor>(
48         DbusEnvironment::serviceName(), sensorObject.path(),
49         DbusEnvironment::getIoc(), DbusEnvironment::getBus());
50     std::shared_ptr<SensorListenerMock> listenerMock =
51         std::make_shared<StrictMock<SensorListenerMock>>();
52     std::shared_ptr<SensorListenerMock> listenerMock2 =
53         std::make_shared<StrictMock<SensorListenerMock>>();
54 };
55 
56 TEST_F(TestSensor, createsCorretlyViaSensorCache)
57 {
58     ASSERT_THAT(sut->id(),
59                 sensorIdEq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
60                                       sensorObject.path())));
61 }
62 
63 TEST_F(TestSensor, notifiesWithValueAfterRegister)
64 {
65     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
66         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
67 
68     registerForUpdates(listenerMock);
69 
70     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
71 }
72 
73 TEST_F(TestSensor, notifiesOnceWithValueAfterRegister)
74 {
75     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
76         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
77     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
78         .WillOnce(
79             InvokeWithoutArgs(DbusEnvironment::setPromise("async_read2")));
80 
81     DbusEnvironment::synchronizedPost([this] {
82         sut->registerForUpdates(listenerMock);
83         sut->registerForUpdates(listenerMock2);
84     });
85 
86     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
87     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
88 }
89 
90 class TestSensorNotification : public TestSensor
91 {
92   public:
93     void SetUp() override
94     {
95         EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
96             .WillOnce(
97                 InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
98 
99         registerForUpdates(listenerMock);
100 
101         ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
102     }
103 
104     std::shared_ptr<SensorListenerMock> listenerMock2 =
105         std::make_shared<StrictMock<SensorListenerMock>>();
106 };
107 
108 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
109 {
110     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
111         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
112 
113     sensorObject.setValue(42.7);
114 
115     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
116 }
117 
118 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenNoChangeOccurs)
119 {
120     Sequence seq;
121 
122     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
123         .InSequence(seq);
124     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp)))
125         .InSequence(seq)
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     Sequence seq;
137     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
138         .InSequence(seq);
139     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
140         .InSequence(seq)
141         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
142 
143     registerForUpdates(listenerMock2);
144     listenerMock = nullptr;
145 
146     sensorObject.setValue(42.7);
147 
148     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
149 }
150 
151 TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
152 {
153     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
154 
155     registerForUpdates(listenerMock2);
156 }
157