blob: 851d4a9d7e542e3241f24ae8cd413f43ab2fc979 [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&
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010072 Updates(std::vector<std::tuple<size_t, Milliseconds, double>> val)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010073 {
74 updates = std::move(val);
75 return *this;
76 }
77
78 NumericParams&
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010079 Expected(std::vector<std::tuple<size_t, Milliseconds, double>> val)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010080 {
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 {
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010091 *os << "{ SensorIndex: " << index
92 << ", Timestamp: " << timestamp.count() << ", Value: " << value
93 << " }, ";
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010094 }
95 *os << "Expected: ";
96 for (const auto& [index, timestamp, value] : o.expected)
97 {
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010098 *os << "{ SensorIndex: " << index
99 << ", Timestamp: " << timestamp.count() << ", Value: " << value
100 << " }, ";
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100101 }
102 *os << " }";
103 }
104
105 numeric::Direction direction;
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100106 std::vector<std::tuple<size_t, Milliseconds, double>> updates;
107 std::vector<std::tuple<size_t, Milliseconds, double>> expected;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100108};
109
110class TestNumericThresholdNoDwellTime :
111 public TestNumericThreshold,
112 public WithParamInterface<NumericParams>
113{
114 public:
115 void SetUp() override
116 {
117 makeThreshold(0ms, GetParam().direction, 90.0);
118 }
119};
120
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100121INSTANTIATE_TEST_SUITE_P(_, TestNumericThresholdNoDwellTime,
122 Values(NumericParams()
123 .Direction(numeric::Direction::increasing)
124 .Updates({{0, 1ms, 80.0}, {0, 2ms, 89.0}})
125 .Expected({}),
126 NumericParams()
127 .Direction(numeric::Direction::increasing)
128 .Updates({{0, 1ms, 80.0}, {0, 2ms, 91.0}})
129 .Expected({{0, 2ms, 91.0}}),
130 NumericParams()
131 .Direction(numeric::Direction::increasing)
132 .Updates({{0, 1ms, 80.0},
133 {0, 2ms, 99.0},
134 {0, 3ms, 80.0},
135 {0, 4ms, 98.0}})
136 .Expected({{0, 2ms, 99.0}, {0, 4ms, 98.0}}),
137 NumericParams()
138 .Direction(numeric::Direction::increasing)
139 .Updates({{0, 1ms, 80.0},
140 {0, 2ms, 99.0},
141 {1, 3ms, 100.0},
142 {1, 4ms, 98.0}})
143 .Expected({{0, 2ms, 99.0}}),
144 NumericParams()
145 .Direction(numeric::Direction::decreasing)
146 .Updates({{0, 1ms, 100.0}, {0, 2ms, 91.0}})
147 .Expected({}),
148 NumericParams()
149 .Direction(numeric::Direction::decreasing)
150 .Updates({{0, 1ms, 100.0}, {0, 2ms, 80.0}})
151 .Expected({{0, 2ms, 80.0}}),
152 NumericParams()
153 .Direction(numeric::Direction::decreasing)
154 .Updates({{0, 1ms, 100.0},
155 {0, 2ms, 80.0},
156 {0, 3ms, 99.0},
157 {0, 4ms, 85.0}})
158 .Expected({{0, 2ms, 80.0}, {0, 4ms, 85.0}}),
159 NumericParams()
160 .Direction(numeric::Direction::decreasing)
161 .Updates({{0, 1ms, 100.0},
162 {0, 2ms, 80.0},
163 {1, 3ms, 99.0},
164 {1, 4ms, 88.0}})
165 .Expected({{0, 2ms, 80.0}, {1, 4ms, 88.0}}),
166 NumericParams()
167 .Direction(numeric::Direction::either)
168 .Updates({{0, 1ms, 98.0}, {0, 2ms, 91.0}})
169 .Expected({}),
170 NumericParams()
171 .Direction(numeric::Direction::either)
172 .Updates({{0, 1ms, 100.0},
173 {0, 2ms, 80.0},
174 {0, 3ms, 85.0},
175 {0, 4ms, 91.0}})
176 .Expected({{0, 2ms, 80.0}, {0, 4ms, 91.0}}),
177 NumericParams()
178 .Direction(numeric::Direction::either)
179 .Updates({{0, 1ms, 100.0},
180 {1, 2ms, 80.0},
181 {0, 3ms, 85.0},
182 {1, 4ms, 91.0}})
183 .Expected({{0, 3ms, 85.0},
184 {1, 4ms, 91.0}})));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100185
186TEST_P(TestNumericThresholdNoDwellTime, senorsIsUpdatedMultipleTimes)
187{
188 InSequence seq;
189 for (const auto& [index, timestamp, value] : GetParam().expected)
190 {
191 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
192 }
193
194 sut->initialize();
195 for (const auto& [index, timestamp, value] : GetParam().updates)
196 {
197 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
198 }
199}
200
201class TestNumericThresholdWithDwellTime :
202 public TestNumericThreshold,
203 public WithParamInterface<NumericParams>
204{
205 public:
206 void SetUp() override
207 {
208 makeThreshold(2ms, GetParam().direction, 90.0);
209 }
210
211 void sleep()
212 {
213 DbusEnvironment::sleepFor(4ms);
214 }
215};
216
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100217INSTANTIATE_TEST_SUITE_P(_, TestNumericThresholdWithDwellTime,
218 Values(NumericParams()
219 .Direction(numeric::Direction::increasing)
220 .Updates({{0, 1ms, 80.0}, {0, 2ms, 89.0}})
221 .Expected({}),
222 NumericParams()
223 .Direction(numeric::Direction::increasing)
224 .Updates({{0, 1ms, 80.0}, {0, 2ms, 91.0}})
225 .Expected({{0, 2ms, 91.0}}),
226 NumericParams()
227 .Direction(numeric::Direction::increasing)
228 .Updates({{0, 1ms, 80.0},
229 {0, 2ms, 99.0},
230 {0, 3ms, 80.0},
231 {0, 4ms, 98.0}})
232 .Expected({{0, 2ms, 99.0}, {0, 4ms, 98.0}}),
233 NumericParams()
234 .Direction(numeric::Direction::increasing)
235 .Updates({{0, 1ms, 80.0},
236 {1, 2ms, 99.0},
237 {0, 3ms, 100.0},
238 {1, 4ms, 86.0}})
239 .Expected({{0, 3ms, 100.0}}),
240 NumericParams()
241 .Direction(numeric::Direction::decreasing)
242 .Updates({{0, 1ms, 100.0}, {0, 2ms, 91.0}})
243 .Expected({}),
244 NumericParams()
245 .Direction(numeric::Direction::decreasing)
246 .Updates({{0, 1ms, 100.0}, {0, 2ms, 80.0}})
247 .Expected({{0, 2ms, 80.0}}),
248 NumericParams()
249 .Direction(numeric::Direction::decreasing)
250 .Updates({{0, 1ms, 100.0},
251 {0, 2ms, 80.0},
252 {0, 3ms, 99.0},
253 {0, 4ms, 85.0}})
254 .Expected({{0, 2ms, 80.0}, {0, 4ms, 85.0}}),
255 NumericParams()
256 .Direction(numeric::Direction::decreasing)
257 .Updates({{0, 1ms, 100.0},
258 {0, 2ms, 80.0},
259 {1, 3ms, 99.0},
260 {1, 4ms, 88.0}})
261 .Expected({{0, 2ms, 80.0}, {1, 4ms, 88.0}}),
262 NumericParams()
263 .Direction(numeric::Direction::either)
264 .Updates({{0, 1ms, 98.0}, {0, 2ms, 91.0}})
265 .Expected({}),
266 NumericParams()
267 .Direction(numeric::Direction::either)
268 .Updates({{0, 1ms, 100.0},
269 {0, 2ms, 80.0},
270 {0, 3ms, 85.0},
271 {0, 4ms, 91.0}})
272 .Expected({{0, 2ms, 80.0}, {0, 4ms, 91.0}}),
273 NumericParams()
274 .Direction(numeric::Direction::either)
275 .Updates({{0, 1ms, 100.0},
276 {1, 2ms, 80.0},
277 {0, 3ms, 85.0},
278 {1, 4ms, 91.0}})
279 .Expected({{0, 3ms, 85.0},
280 {1, 4ms, 91.0}})));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100281
282TEST_P(TestNumericThresholdWithDwellTime,
283 senorsIsUpdatedMultipleTimesSleepAfterEveryUpdate)
284{
285 InSequence seq;
286 for (const auto& [index, timestamp, value] : GetParam().expected)
287 {
288 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
289 }
290
291 sut->initialize();
292 for (const auto& [index, timestamp, value] : GetParam().updates)
293 {
294 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
295 sleep();
296 }
297}
298
299class TestNumericThresholdWithDwellTime2 :
300 public TestNumericThreshold,
301 public WithParamInterface<NumericParams>
302{
303 public:
304 void SetUp() override
305 {
306 makeThreshold(2ms, GetParam().direction, 90.0);
307 }
308
309 void sleep()
310 {
311 DbusEnvironment::sleepFor(4ms);
312 }
313};
314
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100315INSTANTIATE_TEST_SUITE_P(_, TestNumericThresholdWithDwellTime2,
316 Values(NumericParams()
317 .Direction(numeric::Direction::increasing)
318 .Updates({{0, 1ms, 80.0}, {0, 2ms, 89.0}})
319 .Expected({}),
320 NumericParams()
321 .Direction(numeric::Direction::increasing)
322 .Updates({{0, 1ms, 80.0}, {0, 2ms, 91.0}})
323 .Expected({{0, 2ms, 91.0}}),
324 NumericParams()
325 .Direction(numeric::Direction::increasing)
326 .Updates({{0, 1ms, 80.0},
327 {0, 2ms, 99.0},
328 {0, 3ms, 80.0},
329 {0, 4ms, 98.0}})
330 .Expected({{0, 4ms, 98.0}}),
331 NumericParams()
332 .Direction(numeric::Direction::increasing)
333 .Updates({{0, 1ms, 80.0},
334 {1, 2ms, 99.0},
335 {0, 3ms, 100.0},
336 {1, 4ms, 98.0}})
337 .Expected({{0, 3ms, 100.0}}),
338 NumericParams()
339 .Direction(numeric::Direction::decreasing)
340 .Updates({{0, 1ms, 100.0}, {0, 2ms, 91.0}})
341 .Expected({}),
342 NumericParams()
343 .Direction(numeric::Direction::decreasing)
344 .Updates({{0, 1ms, 100.0}, {0, 2ms, 80.0}})
345 .Expected({{0, 2ms, 80.0}}),
346 NumericParams()
347 .Direction(numeric::Direction::decreasing)
348 .Updates({{0, 1ms, 100.0},
349 {0, 2ms, 80.0},
350 {0, 3ms, 99.0},
351 {0, 4ms, 85.0}})
352 .Expected({{0, 4ms, 85.0}}),
353 NumericParams()
354 .Direction(numeric::Direction::decreasing)
355 .Updates({{0, 1ms, 100.0},
356 {0, 2ms, 80.0},
357 {1, 3ms, 99.0},
358 {1, 4ms, 88.0}})
359 .Expected({{0, 2ms, 80.0}, {1, 4ms, 88.0}}),
360 NumericParams()
361 .Direction(numeric::Direction::either)
362 .Updates({{0, 1ms, 98.0}, {0, 2ms, 91.0}})
363 .Expected({}),
364 NumericParams()
365 .Direction(numeric::Direction::either)
366 .Updates({{0, 1ms, 100.0},
367 {0, 2ms, 80.0},
368 {0, 3ms, 85.0},
369 {0, 4ms, 91.0}})
370 .Expected({{0, 4ms, 91.0}}),
371 NumericParams()
372 .Direction(numeric::Direction::either)
373 .Updates({{0, 1ms, 100.0},
374 {1, 2ms, 80.0},
375 {0, 3ms, 85.0},
376 {1, 4ms, 91.0}})
377 .Expected({{0, 3ms, 85.0},
378 {1, 4ms, 91.0}})));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100379
380TEST_P(TestNumericThresholdWithDwellTime2,
381 senorsIsUpdatedMultipleTimesSleepAfterLastUpdate)
382{
383 InSequence seq;
384 for (const auto& [index, timestamp, value] : GetParam().expected)
385 {
386 EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value));
387 }
388
389 sut->initialize();
390 for (const auto& [index, timestamp, value] : GetParam().updates)
391 {
392 sut->sensorUpdated(*sensorMocks[index], timestamp, value);
393 }
394 sleep();
395}