xref: /openbmc/telemetry/tests/src/test_sensor.cpp (revision 0e29f439)
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(InvokeWithoutArgs(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(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
76     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
77         .WillOnce(
78             InvokeWithoutArgs(DbusEnvironment::setPromise("async_read2")));
79 
80     DbusEnvironment::synchronizedPost([this] {
81         sut->registerForUpdates(listenerMock);
82         sut->registerForUpdates(listenerMock2);
83     });
84 
85     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
86     ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
87 }
88 
89 class TestSensorNotification : public TestSensor
90 {
91   public:
92     void SetUp() override
93     {
94         EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
95             .WillOnce(
96                 InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
97 
98         registerForUpdates(listenerMock);
99 
100         ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
101     }
102 
103     std::shared_ptr<SensorListenerMock> listenerMock2 =
104         std::make_shared<StrictMock<SensorListenerMock>>();
105 };
106 
107 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
108 {
109     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
110         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
111 
112     sensorObject.setValue(42.7);
113 
114     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
115 }
116 
117 TEST_F(TestSensorNotification, notifiesListenerWithValueWhenNoChangeOccurs)
118 {
119     Sequence seq;
120 
121     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
122         .InSequence(seq);
123     EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp)))
124         .InSequence(seq)
125         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
126 
127     sensorObject.setValue(42.7);
128     sensorObject.setValue(42.7);
129 
130     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
131 }
132 
133 TEST_F(TestSensorNotification, doesntNotifyExpiredListener)
134 {
135     Sequence seq;
136     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
137         .InSequence(seq);
138     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
139         .InSequence(seq)
140         .WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
141 
142     registerForUpdates(listenerMock2);
143     listenerMock = nullptr;
144 
145     sensorObject.setValue(42.7);
146 
147     ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
148 }
149 
150 TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
151 {
152     EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
153 
154     registerForUpdates(listenerMock2);
155 }
156