blob: 641033782b9e907d801c7981e759d4c21e5fb774 [file] [log] [blame]
Krzysztof Grobelny80697712021-03-04 09:49:27 +00001#include "fakes/clock_fake.hpp"
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +00002#include "helpers.hpp"
Krzysztof Grobelnyc8e3a642020-10-23 12:29:16 +02003#include "metric.hpp"
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01004#include "mocks/metric_listener_mock.hpp"
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01005#include "mocks/sensor_mock.hpp"
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00006#include "params/metric_params.hpp"
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +01007#include "utils/conv_container.hpp"
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +00008#include "utils/conversion.hpp"
9#include "utils/tstring.hpp"
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +010010
11#include <gmock/gmock.h>
12
13using namespace testing;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000014using namespace std::chrono_literals;
15
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000016namespace tstring = utils::tstring;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +010017
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010018constexpr Milliseconds systemTimestamp = 42ms;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +010019
20class TestMetric : public Test
21{
22 public:
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010023 TestMetric()
24 {
25 clockFake.steady.reset();
26 clockFake.system.set(systemTimestamp);
27 }
28
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000029 static std::vector<std::shared_ptr<SensorMock>>
30 makeSensorMocks(size_t amount)
31 {
32 std::vector<std::shared_ptr<SensorMock>> result;
33 for (size_t i = 0; i < amount; ++i)
34 {
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +010035 auto& metricMock =
36 result.emplace_back(std::make_shared<NiceMock<SensorMock>>());
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010037 ON_CALL(*metricMock, metadata())
38 .WillByDefault(Return("metadata" + std::to_string(i)));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000039 }
40 return result;
41 }
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +010042
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000043 std::shared_ptr<Metric> makeSut(const MetricParams& p)
44 {
45 return std::make_shared<Metric>(
46 utils::convContainer<std::shared_ptr<interfaces::Sensor>>(
47 sensorMocks),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +000048 p.operationType(), p.collectionTimeScope(), p.collectionDuration(),
49 std::move(clockFakePtr));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000050 }
51
Krzysztof Grobelny80697712021-03-04 09:49:27 +000052 MetricParams params = MetricParams()
Krzysztof Grobelny80697712021-03-04 09:49:27 +000053 .operationType(OperationType::avg)
54 .collectionTimeScope(CollectionTimeScope::point)
55 .collectionDuration(CollectionDuration(0ms));
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000056 std::vector<std::shared_ptr<SensorMock>> sensorMocks = makeSensorMocks(1u);
Krzysztof Grobelny80697712021-03-04 09:49:27 +000057 std::unique_ptr<ClockFake> clockFakePtr = std::make_unique<ClockFake>();
58 ClockFake& clockFake = *clockFakePtr;
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010059 NiceMock<MetricListenerMock> listenerMock;
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000060 std::shared_ptr<Metric> sut;
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +010061};
62
63TEST_F(TestMetric, subscribesForSensorDuringInitialization)
64{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000065 sut = makeSut(params);
66
67 EXPECT_CALL(*sensorMocks.front(),
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000068 registerForUpdates(Truly([sut = sut.get()](const auto& a0) {
69 return a0.lock().get() == sut;
70 })));
71
72 sut->initialize();
73}
74
Lukasz Kazmierczak7e098e92021-09-16 15:59:56 +020075TEST_F(TestMetric, unsubscribesForSensorDuringDeinitialization)
76{
77 sut = makeSut(params);
78
79 EXPECT_CALL(*sensorMocks.front(),
80 unregisterFromUpdates(Truly([sut = sut.get()](const auto& a0) {
81 return a0.lock().get() == sut;
82 })));
83
84 sut->deinitialize();
85}
86
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +000087TEST_F(TestMetric, containsEmptyReadingAfterCreated)
88{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000089 sut = makeSut(params);
90
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +010091 ASSERT_THAT(sut->getUpdatedReadings(), ElementsAre());
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000092}
93
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010094TEST_F(TestMetric,
95 notifiesRegisteredListenersOnManualUpdateWhenMetricValueChanges)
96{
97 sut = makeSut(params.collectionTimeScope(CollectionTimeScope::startup));
98 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
99 sut->registerForUpdates(listenerMock);
100
101 EXPECT_CALL(listenerMock, metricUpdated()).Times(2);
102
103 sut->updateReadings(Milliseconds{50u});
104 sut->updateReadings(Milliseconds{100u});
105}
106
107TEST_F(TestMetric,
108 doesntNotifyRegisteredListenersOnManualUpdateWhenMetricValueDoesntChange)
109{
110 sut = makeSut(params.collectionTimeScope(CollectionTimeScope::startup)
111 .operationType(OperationType::max));
112 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
113 sut->registerForUpdates(listenerMock);
114
115 EXPECT_CALL(listenerMock, metricUpdated()).Times(0);
116
117 sut->updateReadings(Milliseconds{50u});
118 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{180}, 11.);
119 sut->updateReadings(Milliseconds{100u});
120}
121
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000122class TestMetricAfterInitialization : public TestMetric
123{
124 public:
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000125 void SetUp() override
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100126 {
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000127 sut = makeSut(params);
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000128 sut->initialize();
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100129 }
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000130};
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100131
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000132TEST_F(TestMetricAfterInitialization, containsEmptyReading)
133{
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100134 ASSERT_THAT(sut->getUpdatedReadings(), ElementsAre());
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100135}
136
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000137TEST_F(TestMetricAfterInitialization, updatesMetricValuesOnSensorUpdate)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100138{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100139 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000140
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100141 ASSERT_THAT(
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100142 sut->getUpdatedReadings(),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000143 ElementsAre(MetricValue{"metadata0", 31.2,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100144 std::chrono::duration_cast<Milliseconds>(
145 clockFake.system.timestamp())
146 .count()}));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100147}
148
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000149TEST_F(TestMetricAfterInitialization,
150 throwsWhenUpdateIsPerformedOnUnknownSensor)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100151{
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100152 auto sensor = std::make_shared<StrictMock<SensorMock>>();
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100153 EXPECT_THROW(sut->sensorUpdated(*sensor, Milliseconds{10}, 20.0),
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100154 std::out_of_range);
155}
156
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000157TEST_F(TestMetricAfterInitialization, dumpsConfiguration)
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100158{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000159 namespace ts = utils::tstring;
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000160
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000161 ON_CALL(*sensorMocks.front(), id())
Krzysztof Grobelnye8fc5752021-02-05 14:30:45 +0000162 .WillByDefault(Return(SensorMock::makeId("service1", "path1")));
Krzysztof Grobelnyb8cc78d2021-11-29 15:54:53 +0100163 ON_CALL(*sensorMocks.front(), metadata())
164 .WillByDefault(Return("metadata1"));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100165
Krzysztof Grobelnyd2238192020-12-02 09:27:28 +0000166 const auto conf = sut->dumpConfiguration();
167
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000168 LabeledMetricParameters expected = {};
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000169 expected.at_label<ts::OperationType>() = params.operationType();
170 expected.at_label<ts::CollectionTimeScope>() = params.collectionTimeScope();
171 expected.at_label<ts::CollectionDuration>() = params.collectionDuration();
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000172 expected.at_label<ts::SensorPath>() = {
Szymon Dompke94f71c52021-12-10 07:16:33 +0100173 LabeledSensorInfo("service1", "path1", "metadata1")};
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +0000174
175 EXPECT_THAT(conf, Eq(expected));
Krzysztof Grobelny6ccfcbf2020-11-04 09:31:36 +0100176}
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000177
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100178TEST_F(TestMetricAfterInitialization, notifiesRegisteredListeners)
179{
180 EXPECT_CALL(listenerMock, metricUpdated());
181
182 sut->registerForUpdates(listenerMock);
183 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
184}
185
186TEST_F(TestMetricAfterInitialization,
187 doesntNotifyRegisteredListenersWhenValueDoesntChange)
188{
189 EXPECT_CALL(listenerMock, metricUpdated());
190
191 sut->registerForUpdates(listenerMock);
192 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
193 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{70}, 31.2);
194}
195
196TEST_F(TestMetricAfterInitialization, doesntNotifyAfterUnRegisterListener)
197{
198 EXPECT_CALL(listenerMock, metricUpdated()).Times(0);
199
200 sut->registerForUpdates(listenerMock);
201 sut->unregisterFromUpdates(listenerMock);
202 sut->sensorUpdated(*sensorMocks.front(), Milliseconds{18}, 31.2);
203}
204
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000205class TestMetricCalculationFunctions :
206 public TestMetric,
207 public WithParamInterface<MetricParams>
208{
209 public:
210 void SetUp() override
211 {
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000212 sut = makeSut(params.operationType(GetParam().operationType())
213 .collectionTimeScope(GetParam().collectionTimeScope())
214 .collectionDuration(GetParam().collectionDuration()));
215 }
216
217 static std::vector<std::pair<Milliseconds, double>> defaultReadings()
218 {
219 std::vector<std::pair<Milliseconds, double>> ret;
220 ret.emplace_back(0ms, std::numeric_limits<double>::quiet_NaN());
221 ret.emplace_back(10ms, 14.);
222 ret.emplace_back(1ms, 3.);
223 ret.emplace_back(5ms, 7.);
224 return ret;
225 }
226};
227
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100228MetricParams defaultCollectionFunctionParams()
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000229{
230 return MetricParams()
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000231 .readings(TestMetricCalculationFunctions::defaultReadings())
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100232 .expectedReading(systemTimestamp + 16ms, 7.0);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000233}
234
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000235MetricParams defaultPointParams()
236{
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100237 return defaultCollectionFunctionParams()
238 .collectionTimeScope(CollectionTimeScope::point)
239 .expectedIsTimerRequired(false);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000240}
241
242INSTANTIATE_TEST_SUITE_P(
243 TimeScopePointReturnsLastReading, TestMetricCalculationFunctions,
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100244 Values(defaultPointParams().operationType(OperationType::min),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000245 defaultPointParams().operationType(OperationType::max),
246 defaultPointParams().operationType(OperationType::sum),
247 defaultPointParams().operationType(OperationType::avg)));
248
249MetricParams defaultMinParams()
250{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100251 return defaultCollectionFunctionParams().operationType(OperationType::min);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000252}
253
254INSTANTIATE_TEST_SUITE_P(
255 ReturnsMinForGivenTimeScope, TestMetricCalculationFunctions,
256 Values(defaultMinParams()
257 .collectionTimeScope(CollectionTimeScope::interval)
258 .collectionDuration(CollectionDuration(100ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100259 .expectedReading(systemTimestamp + 16ms, 3.0),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000260 defaultMinParams()
261 .collectionTimeScope(CollectionTimeScope::interval)
262 .collectionDuration(CollectionDuration(3ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100263 .expectedReading(systemTimestamp + 16ms, 7.0),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000264 defaultMinParams()
265 .collectionTimeScope(CollectionTimeScope::startup)
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100266 .expectedReading(systemTimestamp + 16ms, 3.0)
267 .expectedIsTimerRequired(false)));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000268
269MetricParams defaultMaxParams()
270{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100271 return defaultCollectionFunctionParams().operationType(OperationType::max);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000272}
273
274INSTANTIATE_TEST_SUITE_P(
275 ReturnsMaxForGivenTimeScope, TestMetricCalculationFunctions,
276 Values(defaultMaxParams()
277 .collectionTimeScope(CollectionTimeScope::interval)
278 .collectionDuration(CollectionDuration(100ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100279 .expectedReading(systemTimestamp + 16ms, 14.0),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000280 defaultMaxParams()
281 .collectionTimeScope(CollectionTimeScope::interval)
282 .collectionDuration(CollectionDuration(6ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100283 .expectedReading(systemTimestamp + 16ms, 14.0),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000284 defaultMaxParams()
285 .collectionTimeScope(CollectionTimeScope::interval)
286 .collectionDuration(CollectionDuration(5ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100287 .expectedReading(systemTimestamp + 16ms, 7.0),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000288 defaultMaxParams()
289 .collectionTimeScope(CollectionTimeScope::startup)
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100290 .expectedReading(systemTimestamp + 16ms, 14.0)
291 .expectedIsTimerRequired(false)));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000292
293MetricParams defaultSumParams()
294{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100295 return defaultCollectionFunctionParams().operationType(OperationType::sum);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000296}
297
298INSTANTIATE_TEST_SUITE_P(
299 ReturnsSumForGivenTimeScope, TestMetricCalculationFunctions,
300 Values(defaultSumParams()
301 .collectionTimeScope(CollectionTimeScope::interval)
302 .collectionDuration(CollectionDuration(100ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100303 .expectedReading(systemTimestamp + 16ms,
304 14. * 0.01 + 3. * 0.001 + 7. * 0.005),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000305 defaultSumParams()
306 .collectionTimeScope(CollectionTimeScope::interval)
307 .collectionDuration(CollectionDuration(8ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100308 .expectedReading(systemTimestamp + 16ms,
309 14. * 0.002 + 3. * 0.001 + 7 * 0.005),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000310 defaultSumParams()
311 .collectionTimeScope(CollectionTimeScope::interval)
312 .collectionDuration(CollectionDuration(6ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100313 .expectedReading(systemTimestamp + 16ms, 3. * 0.001 + 7 * 0.005),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000314 defaultSumParams()
315 .collectionTimeScope(CollectionTimeScope::startup)
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100316 .expectedReading(systemTimestamp + 16ms,
317 14. * 0.01 + 3. * 0.001 + 7 * 0.005)));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000318
319MetricParams defaultAvgParams()
320{
Krzysztof Grobelny60fee072022-01-13 16:25:04 +0100321 return defaultCollectionFunctionParams().operationType(OperationType::avg);
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000322}
323
324INSTANTIATE_TEST_SUITE_P(
325 ReturnsAvgForGivenTimeScope, TestMetricCalculationFunctions,
326 Values(defaultAvgParams()
327 .collectionTimeScope(CollectionTimeScope::interval)
328 .collectionDuration(CollectionDuration(100ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100329 .expectedReading(systemTimestamp + 16ms,
330 (14. * 10 + 3. * 1 + 7 * 5) / 16.),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000331 defaultAvgParams()
332 .collectionTimeScope(CollectionTimeScope::interval)
333 .collectionDuration(CollectionDuration(8ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100334 .expectedReading(systemTimestamp + 16ms,
335 (14. * 2 + 3. * 1 + 7 * 5) / 8.),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000336 defaultAvgParams()
337 .collectionTimeScope(CollectionTimeScope::interval)
338 .collectionDuration(CollectionDuration(6ms))
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100339 .expectedReading(systemTimestamp + 16ms, (3. * 1 + 7 * 5) / 6.),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000340 defaultAvgParams()
341 .collectionTimeScope(CollectionTimeScope::startup)
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100342 .expectedReading(systemTimestamp + 16ms,
343 (14. * 10 + 3. * 1 + 7 * 5) / 16.)));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000344
345TEST_P(TestMetricCalculationFunctions, calculatesReadingValue)
346{
347 for (auto [timestamp, reading] : GetParam().readings())
348 {
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100349 sut->sensorUpdated(*sensorMocks.front(), clockFake.steadyTimestamp(),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000350 reading);
351 clockFake.advance(timestamp);
352 }
353
Patrick Williams3a1c2972023-05-10 07:51:04 -0500354 const auto [expectedTimestamp,
355 expectedReading] = GetParam().expectedReading();
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100356 const auto readings = sut->getUpdatedReadings();
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000357
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000358 EXPECT_THAT(readings, ElementsAre(MetricValue{"metadata0", expectedReading,
359 expectedTimestamp.count()}));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000360}
361
362TEST_P(TestMetricCalculationFunctions,
363 calculatedReadingValueWithIntermediateCalculations)
364{
365 for (auto [timestamp, reading] : GetParam().readings())
366 {
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +0100367 sut->sensorUpdated(*sensorMocks.front(), clockFake.steadyTimestamp(),
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000368 reading);
369 clockFake.advance(timestamp);
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100370 sut->getUpdatedReadings();
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000371 }
372
Patrick Williams3a1c2972023-05-10 07:51:04 -0500373 const auto [expectedTimestamp,
374 expectedReading] = GetParam().expectedReading();
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100375 const auto readings = sut->getUpdatedReadings();
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000376
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000377 EXPECT_THAT(readings, ElementsAre(MetricValue{"metadata0", expectedReading,
378 expectedTimestamp.count()}));
Krzysztof Grobelny80697712021-03-04 09:49:27 +0000379}
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +0100380
381TEST_P(TestMetricCalculationFunctions, returnsIsTimerRequired)
382{
383 EXPECT_THAT(sut->isTimerRequired(),
384 Eq(GetParam().expectedIsTimerRequired()));
385}
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100386
387class TestMetricWithMultipleSensors : public TestMetric
388{
389 public:
390 TestMetricWithMultipleSensors()
391 {
392 sensorMocks = makeSensorMocks(7u);
393
394 sut = makeSut(params);
395 sut->initialize();
396 }
397};
398
399TEST_F(TestMetricWithMultipleSensors, readingsContainsAllReadingsInOrder)
400{
401 for (size_t i = 0; i < sensorMocks.size(); ++i)
402 {
403 sut->sensorUpdated(*sensorMocks[i], Milliseconds{i + 100}, i + 10.0);
404 sut->getUpdatedReadings();
405 }
406
407 clockFake.system.set(Milliseconds{72});
408
409 EXPECT_THAT(sut->getUpdatedReadings(),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000410 ElementsAre(MetricValue{"metadata0", 10.0, 72},
411 MetricValue{"metadata1", 11.0, 72},
412 MetricValue{"metadata2", 12.0, 72},
413 MetricValue{"metadata3", 13.0, 72},
414 MetricValue{"metadata4", 14.0, 72},
415 MetricValue{"metadata5", 15.0, 72},
416 MetricValue{"metadata6", 16.0, 72}));
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100417}
418
419TEST_F(TestMetricWithMultipleSensors, readingsContainOnlyAvailableSensors)
420{
421 for (auto i : {5u, 3u, 6u, 0u})
422 {
423 sut->sensorUpdated(*sensorMocks[i], Milliseconds{i + 100}, i + 10.0);
424 sut->getUpdatedReadings();
425 }
426
427 clockFake.system.set(Milliseconds{62});
428
429 EXPECT_THAT(sut->getUpdatedReadings(),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000430 ElementsAre(MetricValue{"metadata5", 15.0, 62},
431 MetricValue{"metadata3", 13.0, 62},
432 MetricValue{"metadata6", 16.0, 62},
433 MetricValue{"metadata0", 10.0, 62}));
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100434}
435
436TEST_F(TestMetricWithMultipleSensors, readingsContainsAllReadingsOutOfOrder)
437{
438 for (auto i : {6u, 5u, 3u, 4u, 0u, 2u, 1u})
439 {
440 sut->sensorUpdated(*sensorMocks[i], Milliseconds{i + 100}, i + 10.0);
441 sut->getUpdatedReadings();
442 }
443
444 clockFake.system.set(Milliseconds{52});
445
446 EXPECT_THAT(sut->getUpdatedReadings(),
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000447 ElementsAre(MetricValue{"metadata6", 16.0, 52},
448 MetricValue{"metadata5", 15.0, 52},
449 MetricValue{"metadata3", 13.0, 52},
450 MetricValue{"metadata4", 14.0, 52},
451 MetricValue{"metadata0", 10.0, 52},
452 MetricValue{"metadata2", 12.0, 52},
453 MetricValue{"metadata1", 11.0, 52}));
Krzysztof Grobelny9e8da542022-02-17 10:40:16 +0100454}