blob: c650831f464e4cd83cac5b0e3cff34bec18a8e88 [file] [log] [blame]
Krzysztof Grobelnyb5645942020-09-29 11:52:45 +02001#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
14using namespace testing;
15using namespace std::chrono_literals;
16
17class 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
55TEST_F(TestSensor, createsCorretlyViaSensorCache)
56{
57 ASSERT_THAT(sut->id(),
58 sensorIdEq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
59 sensorObject.path())));
60}
61
62TEST_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
72TEST_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
88class 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
105TEST_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
115TEST_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
131TEST_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
148TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
149{
150 EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
151
152 registerForUpdates(listenerMock2);
153}