blob: bda31a0b3bc303f4fe4702d8d3d020b59dc1eb34 [file] [log] [blame]
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01001#include "dbus_environment.hpp"
2#include "helpers.hpp"
3#include "mocks/sensor_mock.hpp"
4#include "mocks/trigger_action_mock.hpp"
5#include "numeric_threshold.hpp"
6#include "utils/conv_container.hpp"
7
8#include <gmock/gmock.h>
9
10using namespace testing;
11using namespace std::chrono_literals;
12
13class TestNumericThreshold : public Test
14{
15 public:
16 std::vector<std::shared_ptr<SensorMock>> sensorMocks = {
17 std::make_shared<NiceMock<SensorMock>>(),
18 std::make_shared<NiceMock<SensorMock>>()};
19 std::vector<std::string> sensorNames = {"Sensor1", "Sensor2"};
20 std::unique_ptr<TriggerActionMock> actionMockPtr =
21 std::make_unique<StrictMock<TriggerActionMock>>();
22 TriggerActionMock& actionMock = *actionMockPtr;
23 std::shared_ptr<NumericThreshold> sut;
24
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000025 void makeThreshold(Milliseconds dwellTime, numeric::Direction direction,
26 double thresholdValue)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010027 {
28 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
29 actions.push_back(std::move(actionMockPtr));
30
31 sut = std::make_shared<NumericThreshold>(
32 DbusEnvironment::getIoc(),
33 utils::convContainer<std::shared_ptr<interfaces::Sensor>>(
34 sensorMocks),
35 sensorNames, std::move(actions), dwellTime, direction,
36 thresholdValue);
37 }
38
39 void SetUp() override
40 {
41 makeThreshold(0ms, numeric::Direction::increasing, 90.0);
42 }
43};
44
45TEST_F(TestNumericThreshold, initializeThresholdExpectAllSensorsAreRegistered)
46{
47 for (auto& sensor : sensorMocks)
48 {
49 EXPECT_CALL(*sensor,
50 registerForUpdates(Truly([sut = sut.get()](const auto& x) {
51 return x.lock().get() == sut;
52 })));
53 }
54
55 sut->initialize();
56}
57
58TEST_F(TestNumericThreshold, thresholdIsNotInitializeExpectNoActionCommit)
59{
60 EXPECT_CALL(actionMock, commit(_, _, _)).Times(0);
61}
62
63struct NumericParams
64{
65 NumericParams& Direction(numeric::Direction val)
66 {
67 direction = val;
68 return *this;
69 }
70
71 NumericParams&
72 Updates(std::vector<std::tuple<size_t, uint64_t, double>> val)
73 {
74 updates = std::move(val);
75 return *this;
76 }
77
78 NumericParams&
79 Expected(std::vector<std::tuple<size_t, uint64_t, double>> val)
80 {
81 expected = std::move(val);
82 return *this;
83 }
84
85 friend void PrintTo(const NumericParams& o, std::ostream* os)
86 {
87 *os << "{ Direction: " << static_cast<int>(o.direction)
88 << ", Updates: ";
89 for (const auto& [index, timestamp, value] : o.updates)
90 {
91 *os << "{ SensorIndex: " << index << ", Timestamp: " << timestamp
92 << ", Value: " << value << " }, ";
93 }
94 *os << "Expected: ";
95 for (const auto& [index, timestamp, value] : o.expected)
96 {
97 *os << "{ SensorIndex: " << index << ", Timestamp: " << timestamp
98 << ", Value: " << value << " }, ";
99 }
100 *os << " }";
101 }
102
103 numeric::Direction direction;
104 std::vector<std::tuple<size_t, uint64_t, double>> updates;
105 std::vector<std::tuple<size_t, uint64_t, double>> expected;
106};
107
108class TestNumericThresholdNoDwellTime :
109 public TestNumericThreshold,
110 public WithParamInterface<NumericParams>
111{
112 public:
113 void SetUp() override
114 {
115 makeThreshold(0ms, GetParam().direction, 90.0);
116 }
117};
118
119INSTANTIATE_TEST_SUITE_P(
120 _, TestNumericThresholdNoDwellTime,
121 Values(
122 NumericParams()
123 .Direction(numeric::Direction::increasing)
124 .Updates({{0, 1, 80.0}, {0, 2, 89.0}})
125 .Expected({}),
126 NumericParams()
127 .Direction(numeric::Direction::increasing)
128 .Updates({{0, 1, 80.0}, {0, 2, 91.0}})
129 .Expected({{0, 2, 91.0}}),
130 NumericParams()
131 .Direction(numeric::Direction::increasing)
132 .Updates({{0, 1, 80.0}, {0, 2, 99.0}, {0, 3, 80.0}, {0, 4, 98.0}})
133 .Expected({{0, 2, 99.0}, {0, 4, 98.0}}),
134 NumericParams()
135 .Direction(numeric::Direction::increasing)
136 .Updates({{0, 1, 80.0}, {0, 2, 99.0}, {1, 3, 100.0}, {1, 4, 98.0}})
137 .Expected({{0, 2, 99.0}}),
138 NumericParams()
139 .Direction(numeric::Direction::decreasing)
140 .Updates({{0, 1, 100.0}, {0, 2, 91.0}})
141 .Expected({}),
142 NumericParams()
143 .Direction(numeric::Direction::decreasing)
144 .Updates({{0, 1, 100.0}, {0, 2, 80.0}})
145 .Expected({{0, 2, 80.0}}),
146 NumericParams()
147 .Direction(numeric::Direction::decreasing)
148 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 99.0}, {0, 4, 85.0}})
149 .Expected({{0, 2, 80.0}, {0, 4, 85.0}}),
150 NumericParams()
151 .Direction(numeric::Direction::decreasing)
152 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {1, 3, 99.0}, {1, 4, 88.0}})
153 .Expected({{0, 2, 80.0}, {1, 4, 88.0}}),
154 NumericParams()
155 .Direction(numeric::Direction::either)
156 .Updates({{0, 1, 98.0}, {0, 2, 91.0}})
157 .Expected({}),
158 NumericParams()
159 .Direction(numeric::Direction::either)
160 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 85.0}, {0, 4, 91.0}})
161 .Expected({{0, 2, 80.0}, {0, 4, 91.0}}),
162 NumericParams()
163 .Direction(numeric::Direction::either)
164 .Updates({{0, 1, 100.0}, {1, 2, 80.0}, {0, 3, 85.0}, {1, 4, 91.0}})
165 .Expected({{0, 3, 85.0}, {1, 4, 91.0}})));
166
167TEST_P(TestNumericThresholdNoDwellTime, senorsIsUpdatedMultipleTimes)
168{
169 InSequence seq;
170 for (const auto& [index, timestamp, value] : GetParam().expected)
171 {
172 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
173 }
174
175 sut->initialize();
176 for (const auto& [index, timestamp, value] : GetParam().updates)
177 {
178 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
179 }
180}
181
182class TestNumericThresholdWithDwellTime :
183 public TestNumericThreshold,
184 public WithParamInterface<NumericParams>
185{
186 public:
187 void SetUp() override
188 {
189 makeThreshold(2ms, GetParam().direction, 90.0);
190 }
191
192 void sleep()
193 {
194 DbusEnvironment::sleepFor(4ms);
195 }
196};
197
198INSTANTIATE_TEST_SUITE_P(
199 _, TestNumericThresholdWithDwellTime,
200 Values(
201 NumericParams()
202 .Direction(numeric::Direction::increasing)
203 .Updates({{0, 1, 80.0}, {0, 2, 89.0}})
204 .Expected({}),
205 NumericParams()
206 .Direction(numeric::Direction::increasing)
207 .Updates({{0, 1, 80.0}, {0, 2, 91.0}})
208 .Expected({{0, 2, 91.0}}),
209 NumericParams()
210 .Direction(numeric::Direction::increasing)
211 .Updates({{0, 1, 80.0}, {0, 2, 99.0}, {0, 3, 80.0}, {0, 4, 98.0}})
212 .Expected({{0, 2, 99.0}, {0, 4, 98.0}}),
213 NumericParams()
214 .Direction(numeric::Direction::increasing)
215 .Updates({{0, 1, 80.0}, {1, 2, 99.0}, {0, 3, 100.0}, {1, 4, 86.0}})
216 .Expected({{0, 3, 100.0}}),
217 NumericParams()
218 .Direction(numeric::Direction::decreasing)
219 .Updates({{0, 1, 100.0}, {0, 2, 91.0}})
220 .Expected({}),
221 NumericParams()
222 .Direction(numeric::Direction::decreasing)
223 .Updates({{0, 1, 100.0}, {0, 2, 80.0}})
224 .Expected({{0, 2, 80.0}}),
225 NumericParams()
226 .Direction(numeric::Direction::decreasing)
227 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 99.0}, {0, 4, 85.0}})
228 .Expected({{0, 2, 80.0}, {0, 4, 85.0}}),
229 NumericParams()
230 .Direction(numeric::Direction::decreasing)
231 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {1, 3, 99.0}, {1, 4, 88.0}})
232 .Expected({{0, 2, 80.0}, {1, 4, 88.0}}),
233 NumericParams()
234 .Direction(numeric::Direction::either)
235 .Updates({{0, 1, 98.0}, {0, 2, 91.0}})
236 .Expected({}),
237 NumericParams()
238 .Direction(numeric::Direction::either)
239 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 85.0}, {0, 4, 91.0}})
240 .Expected({{0, 2, 80.0}, {0, 4, 91.0}}),
241 NumericParams()
242 .Direction(numeric::Direction::either)
243 .Updates({{0, 1, 100.0}, {1, 2, 80.0}, {0, 3, 85.0}, {1, 4, 91.0}})
244 .Expected({{0, 3, 85.0}, {1, 4, 91.0}})));
245
246TEST_P(TestNumericThresholdWithDwellTime,
247 senorsIsUpdatedMultipleTimesSleepAfterEveryUpdate)
248{
249 InSequence seq;
250 for (const auto& [index, timestamp, value] : GetParam().expected)
251 {
252 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
253 }
254
255 sut->initialize();
256 for (const auto& [index, timestamp, value] : GetParam().updates)
257 {
258 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
259 sleep();
260 }
261}
262
263class TestNumericThresholdWithDwellTime2 :
264 public TestNumericThreshold,
265 public WithParamInterface<NumericParams>
266{
267 public:
268 void SetUp() override
269 {
270 makeThreshold(2ms, GetParam().direction, 90.0);
271 }
272
273 void sleep()
274 {
275 DbusEnvironment::sleepFor(4ms);
276 }
277};
278
279INSTANTIATE_TEST_SUITE_P(
280 _, TestNumericThresholdWithDwellTime2,
281 Values(
282 NumericParams()
283 .Direction(numeric::Direction::increasing)
284 .Updates({{0, 1, 80.0}, {0, 2, 89.0}})
285 .Expected({}),
286 NumericParams()
287 .Direction(numeric::Direction::increasing)
288 .Updates({{0, 1, 80.0}, {0, 2, 91.0}})
289 .Expected({{0, 2, 91.0}}),
290 NumericParams()
291 .Direction(numeric::Direction::increasing)
292 .Updates({{0, 1, 80.0}, {0, 2, 99.0}, {0, 3, 80.0}, {0, 4, 98.0}})
293 .Expected({{0, 4, 98.0}}),
294 NumericParams()
295 .Direction(numeric::Direction::increasing)
296 .Updates({{0, 1, 80.0}, {1, 2, 99.0}, {0, 3, 100.0}, {1, 4, 98.0}})
297 .Expected({{0, 3, 100.0}}),
298 NumericParams()
299 .Direction(numeric::Direction::decreasing)
300 .Updates({{0, 1, 100.0}, {0, 2, 91.0}})
301 .Expected({}),
302 NumericParams()
303 .Direction(numeric::Direction::decreasing)
304 .Updates({{0, 1, 100.0}, {0, 2, 80.0}})
305 .Expected({{0, 2, 80.0}}),
306 NumericParams()
307 .Direction(numeric::Direction::decreasing)
308 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 99.0}, {0, 4, 85.0}})
309 .Expected({{0, 4, 85.0}}),
310 NumericParams()
311 .Direction(numeric::Direction::decreasing)
312 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {1, 3, 99.0}, {1, 4, 88.0}})
313 .Expected({{0, 2, 80.0}, {1, 4, 88.0}}),
314 NumericParams()
315 .Direction(numeric::Direction::either)
316 .Updates({{0, 1, 98.0}, {0, 2, 91.0}})
317 .Expected({}),
318 NumericParams()
319 .Direction(numeric::Direction::either)
320 .Updates({{0, 1, 100.0}, {0, 2, 80.0}, {0, 3, 85.0}, {0, 4, 91.0}})
321 .Expected({{0, 4, 91.0}}),
322 NumericParams()
323 .Direction(numeric::Direction::either)
324 .Updates({{0, 1, 100.0}, {1, 2, 80.0}, {0, 3, 85.0}, {1, 4, 91.0}})
325 .Expected({{0, 3, 85.0}, {1, 4, 91.0}})));
326
327TEST_P(TestNumericThresholdWithDwellTime2,
328 senorsIsUpdatedMultipleTimesSleepAfterLastUpdate)
329{
330 InSequence seq;
331 for (const auto& [index, timestamp, value] : GetParam().expected)
332 {
333 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
334 }
335
336 sut->initialize();
337 for (const auto& [index, timestamp, value] : GetParam().updates)
338 {
339 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
340 }
341 sleep();
342}