blob: 44aa00b3046cb428a28a520643989c0a851ed206 [file] [log] [blame]
Chenjie Yu6736c892017-11-09 10:50:09 -08001// Copyright (C) 2017 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Chenjie Yu054ce9c2018-11-12 15:27:29 -080015#include "src/matchers/SimpleLogMatchingTracker.h"
Chenjie Yu6736c892017-11-09 10:50:09 -080016#include "src/metrics/ValueMetricProducer.h"
Yangster-macb8144812018-01-04 10:56:23 -080017#include "src/stats_log_util.h"
Yao Chenb3561512017-11-21 18:07:17 -080018#include "metrics_test_helper.h"
Yangster-mac94e197c2018-01-02 16:03:03 -080019#include "tests/statsd_test_util.h"
Chenjie Yu6736c892017-11-09 10:50:09 -080020
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
Bookatz6bf98252018-03-14 10:44:24 -070023#include <math.h>
Chenjie Yu6736c892017-11-09 10:50:09 -080024#include <stdio.h>
25#include <vector>
26
27using namespace testing;
28using android::sp;
Yao Chenb3561512017-11-21 18:07:17 -080029using std::make_shared;
Chenjie Yu6736c892017-11-09 10:50:09 -080030using std::set;
Yao Chenb3561512017-11-21 18:07:17 -080031using std::shared_ptr;
Chenjie Yu6736c892017-11-09 10:50:09 -080032using std::unordered_map;
33using std::vector;
Chenjie Yu6736c892017-11-09 10:50:09 -080034
35#ifdef __ANDROID__
36
37namespace android {
38namespace os {
39namespace statsd {
40
Yangster-mac94e197c2018-01-02 16:03:03 -080041const ConfigKey kConfigKey(0, 12345);
Chenjie Yua7259ab2017-12-10 08:31:05 -080042const int tagId = 1;
Yangster-mac94e197c2018-01-02 16:03:03 -080043const int64_t metricId = 123;
Chenjie Yu054ce9c2018-11-12 15:27:29 -080044const int64_t atomMatcherId = 678;
45const int logEventMatcherIndex = 0;
Chenjie Yua7259ab2017-12-10 08:31:05 -080046const int64_t bucketStartTimeNs = 10000000000;
Yangster-macb8144812018-01-04 10:56:23 -080047const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
Chenjie Yua7259ab2017-12-10 08:31:05 -080048const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
49const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
50const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
Chenjie Yu6d370f42018-03-25 14:57:30 -070051const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
52const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
Chenjie Yuc715b9e2018-10-19 07:52:12 -070053double epsilon = 0.001;
54
55/*
56 * Tests that the first bucket works correctly
57 */
58TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
59 ValueMetric metric;
60 metric.set_id(metricId);
61 metric.set_bucket(ONE_MINUTE);
62 metric.mutable_value_field()->set_field(tagId);
63 metric.mutable_value_field()->add_child()->set_field(2);
64
65 int64_t startTimeBase = 11;
Chenjie Yu054ce9c2018-11-12 15:27:29 -080066 UidMap uidMap;
67 SimpleAtomMatcher atomMatcher;
68 atomMatcher.set_atom_id(tagId);
69 sp<EventMatcherWizard> eventMatcherWizard =
70 new EventMatcherWizard({new SimpleLogMatchingTracker(
71 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yuc715b9e2018-10-19 07:52:12 -070072 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
73 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
74
75 // statsd started long ago.
76 // The metric starts in the middle of the bucket
77 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -080078 logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
79 22, pullerManager);
Chenjie Yuc715b9e2018-10-19 07:52:12 -070080
81 EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
82 EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
83 EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
84 valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
85 EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
86 valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
87}
Chenjie Yua7259ab2017-12-10 08:31:05 -080088
Chenjie Yu6736c892017-11-09 10:50:09 -080089/*
Chenjie Yue1361ed2018-07-23 17:33:09 -070090 * Tests that the first bucket works correctly
91 */
92TEST(ValueMetricProducerTest, TestFirstBucket) {
93 ValueMetric metric;
94 metric.set_id(metricId);
95 metric.set_bucket(ONE_MINUTE);
96 metric.mutable_value_field()->set_field(tagId);
97 metric.mutable_value_field()->add_child()->set_field(2);
98
Chenjie Yu054ce9c2018-11-12 15:27:29 -080099 UidMap uidMap;
100 SimpleAtomMatcher atomMatcher;
101 atomMatcher.set_atom_id(tagId);
102 sp<EventMatcherWizard> eventMatcherWizard =
103 new EventMatcherWizard({new SimpleLogMatchingTracker(
104 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yue1361ed2018-07-23 17:33:09 -0700105 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
106 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
107
108 // statsd started long ago.
109 // The metric starts in the middle of the bucket
110 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800111 logEventMatcherIndex, eventMatcherWizard, -1, 5,
112 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
Chenjie Yue1361ed2018-07-23 17:33:09 -0700113
114 EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
115 EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
116 EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
117}
118
119/*
Chenjie Yu6736c892017-11-09 10:50:09 -0800120 * Tests pulled atoms with no conditions
121 */
Chenjie Yue1361ed2018-07-23 17:33:09 -0700122TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
Chenjie Yu6736c892017-11-09 10:50:09 -0800123 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800124 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800125 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800126 metric.mutable_value_field()->set_field(tagId);
127 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu6736c892017-11-09 10:50:09 -0800128
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800129 UidMap uidMap;
130 SimpleAtomMatcher atomMatcher;
131 atomMatcher.set_atom_id(tagId);
132 sp<EventMatcherWizard> eventMatcherWizard =
133 new EventMatcherWizard({new SimpleLogMatchingTracker(
134 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800135 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700136 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700137 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
Chenjie Yu6736c892017-11-09 10:50:09 -0800138 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yue1361ed2018-07-23 17:33:09 -0700139 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
140 .WillOnce(Invoke([](int tagId, int64_t timeNs,
141 vector<std::shared_ptr<LogEvent>>* data) {
142 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700143 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
Chenjie Yue1361ed2018-07-23 17:33:09 -0700144 event->write(tagId);
145 event->write(3);
146 event->init();
147 data->push_back(event);
148 return true;
149 }));
Chenjie Yu6736c892017-11-09 10:50:09 -0800150
Yao Chenb3561512017-11-21 18:07:17 -0800151 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800152 logEventMatcherIndex, eventMatcherWizard, tagId,
153 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu6736c892017-11-09 10:50:09 -0800154
155 vector<shared_ptr<LogEvent>> allData;
156 allData.clear();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800157 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
158 event->write(tagId);
Yao Chen80235402017-11-13 20:42:25 -0800159 event->write(11);
Chenjie Yu6736c892017-11-09 10:50:09 -0800160 event->init();
161 allData.push_back(event);
162
163 valueProducer.onDataPulled(allData);
164 // has one slice
165 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700166 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
yro59cc24d2018-02-13 20:17:32 -0800167
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700168 EXPECT_EQ(true, curInterval.hasBase);
169 EXPECT_EQ(11, curInterval.base.long_value);
170 EXPECT_EQ(true, curInterval.hasValue);
171 EXPECT_EQ(8, curInterval.value.long_value);
172 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6736c892017-11-09 10:50:09 -0800173
174 allData.clear();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800175 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
176 event->write(tagId);
177 event->write(23);
Chenjie Yu6736c892017-11-09 10:50:09 -0800178 event->init();
179 allData.push_back(event);
180 valueProducer.onDataPulled(allData);
181 // has one slice
182 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700183 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700184
185 EXPECT_EQ(true, curInterval.hasBase);
186 EXPECT_EQ(23, curInterval.base.long_value);
187 EXPECT_EQ(true, curInterval.hasValue);
188 EXPECT_EQ(12, curInterval.value.long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800189 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700190 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700191 EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800192
193 allData.clear();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800194 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
195 event->write(tagId);
196 event->write(36);
Chenjie Yu6736c892017-11-09 10:50:09 -0800197 event->init();
198 allData.push_back(event);
199 valueProducer.onDataPulled(allData);
200 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700201 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700202
203 EXPECT_EQ(true, curInterval.hasBase);
204 EXPECT_EQ(36, curInterval.base.long_value);
205 EXPECT_EQ(true, curInterval.hasValue);
206 EXPECT_EQ(13, curInterval.value.long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800207 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700208 EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700209 EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800210}
211
212/*
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800213 * Tests pulled atoms with filtering
214 */
215TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
216 ValueMetric metric;
217 metric.set_id(metricId);
218 metric.set_bucket(ONE_MINUTE);
219 metric.mutable_value_field()->set_field(tagId);
220 metric.mutable_value_field()->add_child()->set_field(2);
221
222 UidMap uidMap;
223 SimpleAtomMatcher atomMatcher;
224 atomMatcher.set_atom_id(tagId);
225 auto keyValue = atomMatcher.add_field_value_matcher();
226 keyValue->set_field(1);
227 keyValue->set_eq_int(3);
228 sp<EventMatcherWizard> eventMatcherWizard =
229 new EventMatcherWizard({new SimpleLogMatchingTracker(
230 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
231 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
232 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
233 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
234 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
235 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
236 .WillOnce(Invoke([](int tagId, int64_t timeNs,
237 vector<std::shared_ptr<LogEvent>>* data) {
238 data->clear();
239 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
240 event->write(3);
241 event->write(3);
242 event->init();
243 data->push_back(event);
244 return true;
245 }));
246
247 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
248 logEventMatcherIndex, eventMatcherWizard, tagId,
249 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
250
251 vector<shared_ptr<LogEvent>> allData;
252 allData.clear();
253 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
254 event->write(3);
255 event->write(11);
256 event->init();
257 allData.push_back(event);
258
259 valueProducer.onDataPulled(allData);
260 // has one slice
261 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
262 ValueMetricProducer::Interval curInterval =
263 valueProducer.mCurrentSlicedBucket.begin()->second[0];
264
265 EXPECT_EQ(true, curInterval.hasBase);
266 EXPECT_EQ(11, curInterval.base.long_value);
267 EXPECT_EQ(true, curInterval.hasValue);
268 EXPECT_EQ(8, curInterval.value.long_value);
269 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
270
271 allData.clear();
272 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
273 event->write(4);
274 event->write(23);
275 event->init();
276 allData.push_back(event);
277 valueProducer.onDataPulled(allData);
278 // has one slice
279 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
280 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
281
282 EXPECT_EQ(true, curInterval.hasBase);
283 EXPECT_EQ(11, curInterval.base.long_value);
284 // no events caused flush of bucket
285 EXPECT_EQ(true, curInterval.hasValue);
286 EXPECT_EQ(8, curInterval.value.long_value);
287 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
288
289 allData.clear();
290 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
291 event->write(3);
292 event->write(36);
293 event->init();
294 allData.push_back(event);
295 valueProducer.onDataPulled(allData);
296 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
297 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
298
299 // the base was reset
300 EXPECT_EQ(true, curInterval.hasBase);
301 EXPECT_EQ(36, curInterval.base.long_value);
302 EXPECT_EQ(false, curInterval.hasValue);
303 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
304 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
305 EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
306}
307
308/*
Chenjie Yu021e2532018-05-16 12:23:07 -0700309 * Tests pulled atoms with no conditions and take absolute value after reset
310 */
311TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
312 ValueMetric metric;
313 metric.set_id(metricId);
314 metric.set_bucket(ONE_MINUTE);
315 metric.mutable_value_field()->set_field(tagId);
316 metric.mutable_value_field()->add_child()->set_field(2);
317 metric.set_use_absolute_value_on_reset(true);
318
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800319 UidMap uidMap;
320 SimpleAtomMatcher atomMatcher;
321 atomMatcher.set_atom_id(tagId);
322 sp<EventMatcherWizard> eventMatcherWizard =
323 new EventMatcherWizard({new SimpleLogMatchingTracker(
324 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700325 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700326 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700327 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
328 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700329 EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
Chenjie Yu021e2532018-05-16 12:23:07 -0700330
331 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800332 logEventMatcherIndex, eventMatcherWizard, tagId,
333 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700334
335 vector<shared_ptr<LogEvent>> allData;
336 allData.clear();
337 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
338 event->write(tagId);
339 event->write(11);
340 event->init();
341 allData.push_back(event);
342
343 valueProducer.onDataPulled(allData);
344 // has one slice
345 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700346 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu021e2532018-05-16 12:23:07 -0700347
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700348 EXPECT_EQ(true, curInterval.hasBase);
349 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700350 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700351 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
352
353 allData.clear();
354 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
355 event->write(tagId);
356 event->write(10);
357 event->init();
358 allData.push_back(event);
359 valueProducer.onDataPulled(allData);
360 // has one slice
361 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700362 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700363 EXPECT_EQ(true, curInterval.hasBase);
364 EXPECT_EQ(10, curInterval.base.long_value);
365 EXPECT_EQ(true, curInterval.hasValue);
366 EXPECT_EQ(10, curInterval.value.long_value);
367 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700368
369 allData.clear();
370 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
371 event->write(tagId);
372 event->write(36);
373 event->init();
374 allData.push_back(event);
375 valueProducer.onDataPulled(allData);
376 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700377 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700378 EXPECT_EQ(true, curInterval.hasBase);
379 EXPECT_EQ(36, curInterval.base.long_value);
380 EXPECT_EQ(true, curInterval.hasValue);
381 EXPECT_EQ(26, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700382 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700383 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700384 EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700385}
386
387/*
388 * Tests pulled atoms with no conditions and take zero value after reset
389 */
390TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
391 ValueMetric metric;
392 metric.set_id(metricId);
393 metric.set_bucket(ONE_MINUTE);
394 metric.mutable_value_field()->set_field(tagId);
395 metric.mutable_value_field()->add_child()->set_field(2);
396
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800397 UidMap uidMap;
398 SimpleAtomMatcher atomMatcher;
399 atomMatcher.set_atom_id(tagId);
400 sp<EventMatcherWizard> eventMatcherWizard =
401 new EventMatcherWizard({new SimpleLogMatchingTracker(
402 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700403 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700404 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700405 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
406 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yue1361ed2018-07-23 17:33:09 -0700407 EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
Chenjie Yu021e2532018-05-16 12:23:07 -0700408
409 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800410 logEventMatcherIndex, eventMatcherWizard, tagId,
411 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700412
413 vector<shared_ptr<LogEvent>> allData;
414 allData.clear();
415 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
416 event->write(tagId);
417 event->write(11);
418 event->init();
419 allData.push_back(event);
420
421 valueProducer.onDataPulled(allData);
422 // has one slice
423 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700424 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu021e2532018-05-16 12:23:07 -0700425
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700426 EXPECT_EQ(true, curInterval.hasBase);
427 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700428 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700429 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
430
431 allData.clear();
432 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
433 event->write(tagId);
434 event->write(10);
435 event->init();
436 allData.push_back(event);
437 valueProducer.onDataPulled(allData);
438 // has one slice
439 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700440 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700441 EXPECT_EQ(true, curInterval.hasBase);
442 EXPECT_EQ(10, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700443 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700444 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
445
446 allData.clear();
447 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
448 event->write(tagId);
449 event->write(36);
450 event->init();
451 allData.push_back(event);
452 valueProducer.onDataPulled(allData);
453 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700454 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700455 EXPECT_EQ(true, curInterval.hasBase);
456 EXPECT_EQ(36, curInterval.base.long_value);
457 EXPECT_EQ(true, curInterval.hasValue);
458 EXPECT_EQ(26, curInterval.value.long_value);
459 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700460}
461
462/*
Chenjie Yu6736c892017-11-09 10:50:09 -0800463 * Test pulled event with non sliced condition.
464 */
465TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
Chenjie Yu6736c892017-11-09 10:50:09 -0800466 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800467 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800468 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800469 metric.mutable_value_field()->set_field(tagId);
470 metric.mutable_value_field()->add_child()->set_field(2);
Yangster-mac94e197c2018-01-02 16:03:03 -0800471 metric.set_condition(StringToId("SCREEN_ON"));
Chenjie Yu6736c892017-11-09 10:50:09 -0800472
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800473 UidMap uidMap;
474 SimpleAtomMatcher atomMatcher;
475 atomMatcher.set_atom_id(tagId);
476 sp<EventMatcherWizard> eventMatcherWizard =
477 new EventMatcherWizard({new SimpleLogMatchingTracker(
478 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800479 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700480 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700481 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
Chenjie Yu6736c892017-11-09 10:50:09 -0800482 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
483
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700484 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
Chenjie Yue1361ed2018-07-23 17:33:09 -0700485 .WillOnce(Invoke([](int tagId, int64_t timeNs,
486 vector<std::shared_ptr<LogEvent>>* data) {
487 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700488 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800489 event->write(tagId);
Yao Chenb3561512017-11-21 18:07:17 -0800490 event->write(100);
491 event->init();
492 data->push_back(event);
493 return true;
494 }))
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700495 .WillOnce(Invoke([](int tagId, int64_t timeNs,
496 vector<std::shared_ptr<LogEvent>>* data) {
Yao Chenb3561512017-11-21 18:07:17 -0800497 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700498 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800499 event->write(tagId);
Yao Chenb3561512017-11-21 18:07:17 -0800500 event->write(120);
501 event->init();
502 data->push_back(event);
503 return true;
504 }));
Chenjie Yu6736c892017-11-09 10:50:09 -0800505
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800506 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
507 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700508 bucketStartTimeNs, pullerManager);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800509 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
Chenjie Yu6736c892017-11-09 10:50:09 -0800510
511 // has one slice
512 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700513 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700514 // startUpdated:false sum:0 start:100
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700515 EXPECT_EQ(true, curInterval.hasBase);
516 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700517 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6736c892017-11-09 10:50:09 -0800518 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
519
520 vector<shared_ptr<LogEvent>> allData;
521 allData.clear();
522 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Yao Chen80235402017-11-13 20:42:25 -0800523 event->write(1);
524 event->write(110);
Chenjie Yu6736c892017-11-09 10:50:09 -0800525 event->init();
526 allData.push_back(event);
527 valueProducer.onDataPulled(allData);
528
529 // has one slice
530 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700531 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700532 EXPECT_EQ(true, curInterval.hasBase);
533 EXPECT_EQ(110, curInterval.base.long_value);
534 EXPECT_EQ(true, curInterval.hasValue);
535 EXPECT_EQ(10, curInterval.value.long_value);
536 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6736c892017-11-09 10:50:09 -0800537
538 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
539
540 // has one slice
541 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700542 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700543 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yua0f02242018-07-06 16:14:34 -0700544 EXPECT_EQ(10, curInterval.value.long_value);
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700545 EXPECT_EQ(false, curInterval.hasBase);
Chenjie Yu6736c892017-11-09 10:50:09 -0800546}
547
David Chen27785a82018-01-19 17:06:45 -0800548TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
549 ValueMetric metric;
550 metric.set_id(metricId);
551 metric.set_bucket(ONE_MINUTE);
552 metric.mutable_value_field()->set_field(tagId);
553 metric.mutable_value_field()->add_child()->set_field(2);
554
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800555 UidMap uidMap;
556 SimpleAtomMatcher atomMatcher;
557 atomMatcher.set_atom_id(tagId);
558 sp<EventMatcherWizard> eventMatcherWizard =
559 new EventMatcherWizard({new SimpleLogMatchingTracker(
560 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen27785a82018-01-19 17:06:45 -0800561 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700562 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800563 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
564 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
565 pullerManager);
David Chen27785a82018-01-19 17:06:45 -0800566
567 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
568 event1->write(1);
569 event1->write(10);
570 event1->init();
571 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
572 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
573
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700574 valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
David Chen27785a82018-01-19 17:06:45 -0800575 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700576 EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800577
578 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
579 event2->write(1);
580 event2->write(10);
581 event2->init();
582 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
583 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700584 EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800585
586 // Next value should create a new bucket.
587 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
588 event3->write(1);
589 event3->write(10);
590 event3->init();
591 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
592 EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Yangster-macb142cc82018-03-30 15:22:08 -0700593 EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800594}
595
596TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
597 ValueMetric metric;
598 metric.set_id(metricId);
599 metric.set_bucket(ONE_MINUTE);
600 metric.mutable_value_field()->set_field(tagId);
601 metric.mutable_value_field()->add_child()->set_field(2);
602
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800603 UidMap uidMap;
604 SimpleAtomMatcher atomMatcher;
605 atomMatcher.set_atom_id(tagId);
606 sp<EventMatcherWizard> eventMatcherWizard =
607 new EventMatcherWizard({new SimpleLogMatchingTracker(
608 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen27785a82018-01-19 17:06:45 -0800609 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700610 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700611 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
David Chen27785a82018-01-19 17:06:45 -0800612 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700613 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700614 .WillOnce(Return(true))
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700615 .WillOnce(Invoke([](int tagId, int64_t timeNs,
616 vector<std::shared_ptr<LogEvent>>* data) {
David Chen27785a82018-01-19 17:06:45 -0800617 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700618 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
David Chen27785a82018-01-19 17:06:45 -0800619 event->write(tagId);
620 event->write(120);
621 event->init();
622 data->push_back(event);
623 return true;
624 }));
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800625 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
626 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700627 bucketStartTimeNs, pullerManager);
David Chen27785a82018-01-19 17:06:45 -0800628
629 vector<shared_ptr<LogEvent>> allData;
630 allData.clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700631 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
David Chen27785a82018-01-19 17:06:45 -0800632 event->write(tagId);
633 event->write(100);
634 event->init();
635 allData.push_back(event);
636
637 valueProducer.onDataPulled(allData);
638 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
639
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700640 valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
David Chen27785a82018-01-19 17:06:45 -0800641 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700642 EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
Chenjie Yu32717c32018-10-20 23:54:48 -0700643 EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
David Chen27785a82018-01-19 17:06:45 -0800644
645 allData.clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700646 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
David Chen27785a82018-01-19 17:06:45 -0800647 event->write(tagId);
648 event->write(150);
649 event->init();
650 allData.push_back(event);
651 valueProducer.onDataPulled(allData);
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700652 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
653 EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
Chenjie Yu32717c32018-10-20 23:54:48 -0700654 EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
David Chen27785a82018-01-19 17:06:45 -0800655}
656
David Chen092a5a92018-05-15 17:50:32 -0700657TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
658 ValueMetric metric;
659 metric.set_id(metricId);
660 metric.set_bucket(ONE_MINUTE);
661 metric.mutable_value_field()->set_field(tagId);
662 metric.mutable_value_field()->add_child()->set_field(2);
663 metric.set_condition(StringToId("SCREEN_ON"));
664
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800665 UidMap uidMap;
666 SimpleAtomMatcher atomMatcher;
667 atomMatcher.set_atom_id(tagId);
668 sp<EventMatcherWizard> eventMatcherWizard =
669 new EventMatcherWizard({new SimpleLogMatchingTracker(
670 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen092a5a92018-05-15 17:50:32 -0700671 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700672 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
David Chen092a5a92018-05-15 17:50:32 -0700673 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
674 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
675 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
676 .WillOnce(Invoke([](int tagId, int64_t timeNs,
677 vector<std::shared_ptr<LogEvent>>* data) {
678 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700679 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
David Chen092a5a92018-05-15 17:50:32 -0700680 event->write(tagId);
681 event->write(100);
682 event->init();
683 data->push_back(event);
684 return true;
685 }))
686 .WillOnce(Invoke([](int tagId, int64_t timeNs,
687 vector<std::shared_ptr<LogEvent>>* data) {
688 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700689 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
David Chen092a5a92018-05-15 17:50:32 -0700690 event->write(tagId);
691 event->write(120);
692 event->init();
693 data->push_back(event);
694 return true;
695 }));
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800696 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
697 eventMatcherWizard, tagId, bucketStartTimeNs,
David Chen092a5a92018-05-15 17:50:32 -0700698 bucketStartTimeNs, pullerManager);
David Chen092a5a92018-05-15 17:50:32 -0700699 valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
700
701 valueProducer.onConditionChanged(false, bucket2StartTimeNs-100);
702 EXPECT_FALSE(valueProducer.mCondition);
703
704 valueProducer.notifyAppUpgrade(bucket2StartTimeNs-50, "ANY.APP", 1, 1);
705 // Expect one full buckets already done and starting a partial bucket.
706 EXPECT_EQ(bucket2StartTimeNs-50, valueProducer.mCurrentBucketStartTimeNs);
707 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
708 EXPECT_EQ(bucketStartTimeNs, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
Chenjie Yu32717c32018-10-20 23:54:48 -0700709 EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
David Chen092a5a92018-05-15 17:50:32 -0700710 EXPECT_FALSE(valueProducer.mCondition);
711}
712
Chenjie Yu6736c892017-11-09 10:50:09 -0800713TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
Chenjie Yu6736c892017-11-09 10:50:09 -0800714 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800715 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800716 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800717 metric.mutable_value_field()->set_field(tagId);
718 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu6736c892017-11-09 10:50:09 -0800719
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800720 UidMap uidMap;
721 SimpleAtomMatcher atomMatcher;
722 atomMatcher.set_atom_id(tagId);
723 sp<EventMatcherWizard> eventMatcherWizard =
724 new EventMatcherWizard({new SimpleLogMatchingTracker(
725 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800726 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700727 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6736c892017-11-09 10:50:09 -0800728
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800729 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
730 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
731 pullerManager);
Chenjie Yu6736c892017-11-09 10:50:09 -0800732
733 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
Yao Chen80235402017-11-13 20:42:25 -0800734 event1->write(1);
735 event1->write(10);
Chenjie Yu6736c892017-11-09 10:50:09 -0800736 event1->init();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800737 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
Yao Chen80235402017-11-13 20:42:25 -0800738 event2->write(1);
739 event2->write(20);
Chenjie Yu6736c892017-11-09 10:50:09 -0800740 event2->init();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800741 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
Chenjie Yu6736c892017-11-09 10:50:09 -0800742 // has one slice
743 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700744 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700745 EXPECT_EQ(10, curInterval.value.long_value);
746 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yu6736c892017-11-09 10:50:09 -0800747
Chenjie Yua7259ab2017-12-10 08:31:05 -0800748 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Chenjie Yu6736c892017-11-09 10:50:09 -0800749
750 // has one slice
751 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700752 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700753 EXPECT_EQ(30, curInterval.value.long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800754
Yangsterf2bee6f2017-11-29 12:01:05 -0800755 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
Chenjie Yu6736c892017-11-09 10:50:09 -0800756 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
757 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700758 EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800759}
760
Chenjie Yu021e2532018-05-16 12:23:07 -0700761TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
762 ValueMetric metric;
763 metric.set_id(metricId);
764 metric.set_bucket(ONE_MINUTE);
765 metric.mutable_value_field()->set_field(tagId);
766 metric.mutable_value_field()->add_child()->set_field(2);
767
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800768 UidMap uidMap;
769 SimpleAtomMatcher atomMatcher;
770 atomMatcher.set_atom_id(tagId);
771 sp<EventMatcherWizard> eventMatcherWizard =
772 new EventMatcherWizard({new SimpleLogMatchingTracker(
773 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700774 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700775 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700776
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800777 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
778 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
779 pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700780
781 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
782 event1->write(1);
783 event1->write(10);
784 event1->init();
785 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
786 // has 1 slice
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700787 EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700788
789 valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
790 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
791 event2->write(1);
792 event2->write(20);
793 event2->init();
794 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
795
796 // has one slice
797 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700798 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
799 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700800 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700801
802 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
803 event3->write(1);
804 event3->write(30);
805 event3->init();
806 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
807
808 // has one slice
809 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700810 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700811 EXPECT_EQ(50, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700812
813 valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
814 shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 40);
815 event4->write(1);
816 event4->write(40);
817 event4->init();
818 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
819
820 // has one slice
821 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700822 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700823 EXPECT_EQ(50, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700824
825 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
826 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
827 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700828 EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700829}
830
Bookatzde1b55622017-12-14 18:38:27 -0800831TEST(ValueMetricProducerTest, TestAnomalyDetection) {
Yangster-mac932ecec2018-02-01 10:23:52 -0800832 sp<AlarmMonitor> alarmMonitor;
Bookatzde1b55622017-12-14 18:38:27 -0800833 Alert alert;
Yangster-mac94e197c2018-01-02 16:03:03 -0800834 alert.set_id(101);
835 alert.set_metric_id(metricId);
Bookatzde1b55622017-12-14 18:38:27 -0800836 alert.set_trigger_if_sum_gt(130);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800837 alert.set_num_buckets(2);
Bookatz1bf94382018-01-04 11:43:20 -0800838 const int32_t refPeriodSec = 3;
839 alert.set_refractory_period_secs(refPeriodSec);
Bookatzde1b55622017-12-14 18:38:27 -0800840
841 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800842 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800843 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800844 metric.mutable_value_field()->set_field(tagId);
845 metric.mutable_value_field()->add_child()->set_field(2);
Bookatzde1b55622017-12-14 18:38:27 -0800846
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800847 UidMap uidMap;
848 SimpleAtomMatcher atomMatcher;
849 atomMatcher.set_atom_id(tagId);
850 sp<EventMatcherWizard> eventMatcherWizard =
851 new EventMatcherWizard({new SimpleLogMatchingTracker(
852 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Bookatzde1b55622017-12-14 18:38:27 -0800853 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700854 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Bookatzde1b55622017-12-14 18:38:27 -0800855 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800856 logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
857 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
yro59cc24d2018-02-13 20:17:32 -0800858
Yangster-mac932ecec2018-02-01 10:23:52 -0800859 sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
Bookatzde1b55622017-12-14 18:38:27 -0800860
861
862 shared_ptr<LogEvent> event1
863 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1 * NS_PER_SEC);
864 event1->write(161);
865 event1->write(10); // value of interest
866 event1->init();
867 shared_ptr<LogEvent> event2
868 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 + NS_PER_SEC);
869 event2->write(162);
870 event2->write(20); // value of interest
871 event2->init();
872 shared_ptr<LogEvent> event3
873 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC);
874 event3->write(163);
875 event3->write(130); // value of interest
876 event3->init();
877 shared_ptr<LogEvent> event4
878 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC);
879 event4->write(35);
880 event4->write(1); // value of interest
881 event4->init();
882 shared_ptr<LogEvent> event5
883 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC);
884 event5->write(45);
885 event5->write(150); // value of interest
886 event5->init();
887 shared_ptr<LogEvent> event6
888 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC);
889 event6->write(25);
890 event6->write(160); // value of interest
891 event6->init();
892
893 // Two events in bucket #0.
894 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
895 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Bookatz1bf94382018-01-04 11:43:20 -0800896 // Value sum == 30 <= 130.
Yangster-mac93694462018-01-22 20:49:31 -0800897 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
Bookatzde1b55622017-12-14 18:38:27 -0800898
899 // One event in bucket #2. No alarm as bucket #0 is trashed out.
900 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
Bookatz1bf94382018-01-04 11:43:20 -0800901 // Value sum == 130 <= 130.
Yangster-mac93694462018-01-22 20:49:31 -0800902 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
Bookatzde1b55622017-12-14 18:38:27 -0800903
904 // Three events in bucket #3.
905 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
906 // Anomaly at event 4 since Value sum == 131 > 130!
Yangster-mac93694462018-01-22 20:49:31 -0800907 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700908 std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800909 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event5);
910 // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
Yangster-mac93694462018-01-22 20:49:31 -0800911 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700912 std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800913
914 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event6);
915 // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
Yangster-mac93694462018-01-22 20:49:31 -0800916 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700917 std::ceil(1.0 * event6->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800918}
919
Chenjie Yu6d370f42018-03-25 14:57:30 -0700920// Test value metric no condition, the pull on bucket boundary come in time and too late
921TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
922 ValueMetric metric;
923 metric.set_id(metricId);
924 metric.set_bucket(ONE_MINUTE);
925 metric.mutable_value_field()->set_field(tagId);
926 metric.mutable_value_field()->add_child()->set_field(2);
927
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800928 UidMap uidMap;
929 SimpleAtomMatcher atomMatcher;
930 atomMatcher.set_atom_id(tagId);
931 sp<EventMatcherWizard> eventMatcherWizard =
932 new EventMatcherWizard({new SimpleLogMatchingTracker(
933 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -0700934 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700935 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -0700936 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
937 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700938 EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
Chenjie Yu6d370f42018-03-25 14:57:30 -0700939
940 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800941 logEventMatcherIndex, eventMatcherWizard, tagId,
942 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -0700943
944 vector<shared_ptr<LogEvent>> allData;
945 // pull 1
946 allData.clear();
947 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
948 event->write(tagId);
949 event->write(11);
950 event->init();
951 allData.push_back(event);
952
953 valueProducer.onDataPulled(allData);
954 // has one slice
955 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700956 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu6d370f42018-03-25 14:57:30 -0700957
Chenjie Yua0f02242018-07-06 16:14:34 -0700958 // startUpdated:true sum:0 start:11
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700959 EXPECT_EQ(true, curInterval.hasBase);
960 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700961 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yuae63b0a2018-04-10 14:59:31 -0700962 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -0700963
964 // pull 2 at correct time
965 allData.clear();
966 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
967 event->write(tagId);
968 event->write(23);
969 event->init();
970 allData.push_back(event);
971 valueProducer.onDataPulled(allData);
972 // has one slice
973 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700974 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700975 // tartUpdated:false sum:12
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700976 EXPECT_EQ(true, curInterval.hasBase);
977 EXPECT_EQ(23, curInterval.base.long_value);
978 EXPECT_EQ(true, curInterval.hasValue);
979 EXPECT_EQ(12, curInterval.value.long_value);
980 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -0700981
982 // pull 3 come late.
983 // The previous bucket gets closed with error. (Has start value 23, no ending)
984 // Another bucket gets closed with error. (No start, but ending with 36)
985 // The new bucket is back to normal.
986 allData.clear();
987 event = make_shared<LogEvent>(tagId, bucket6StartTimeNs + 1);
988 event->write(tagId);
989 event->write(36);
990 event->init();
991 allData.push_back(event);
992 valueProducer.onDataPulled(allData);
993 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700994 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700995 // startUpdated:false sum:12
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700996 EXPECT_EQ(true, curInterval.hasBase);
997 EXPECT_EQ(36, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700998 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -0700999 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001000 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001001 EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001002}
1003
1004/*
1005 * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
1006 * was delivered late.
1007 */
1008TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
1009 ValueMetric metric;
1010 metric.set_id(metricId);
1011 metric.set_bucket(ONE_MINUTE);
1012 metric.mutable_value_field()->set_field(tagId);
1013 metric.mutable_value_field()->add_child()->set_field(2);
1014 metric.set_condition(StringToId("SCREEN_ON"));
1015
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001016 UidMap uidMap;
1017 SimpleAtomMatcher atomMatcher;
1018 atomMatcher.set_atom_id(tagId);
1019 sp<EventMatcherWizard> eventMatcherWizard =
1020 new EventMatcherWizard({new SimpleLogMatchingTracker(
1021 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -07001022 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -07001023 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -07001024 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1025 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1026
1027 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
1028 // condition becomes true
1029 .WillOnce(Invoke([](int tagId, int64_t timeNs,
1030 vector<std::shared_ptr<LogEvent>>* data) {
1031 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001032 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001033 event->write(tagId);
1034 event->write(100);
1035 event->init();
1036 data->push_back(event);
1037 return true;
1038 }))
1039 // condition becomes false
1040 .WillOnce(Invoke([](int tagId, int64_t timeNs,
1041 vector<std::shared_ptr<LogEvent>>* data) {
1042 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001043 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001044 event->write(tagId);
1045 event->write(120);
1046 event->init();
1047 data->push_back(event);
1048 return true;
1049 }));
1050
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001051 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1052 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -07001053 bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001054 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
1055
1056 // has one slice
1057 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001058 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001059 EXPECT_EQ(true, curInterval.hasBase);
1060 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001061 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001062 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1063
1064 // pull on bucket boundary come late, condition change happens before it
1065 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
Chenjie Yu32717c32018-10-20 23:54:48 -07001066 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001067 EXPECT_EQ(false, curInterval.hasBase);
1068 EXPECT_EQ(true, curInterval.hasValue);
1069 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001070 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001071
1072 // Now the alarm is delivered.
1073 // since the condition turned to off before this pull finish, it has no effect
1074 vector<shared_ptr<LogEvent>> allData;
1075 allData.clear();
1076 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 30);
1077 event->write(1);
1078 event->write(110);
1079 event->init();
1080 allData.push_back(event);
1081 valueProducer.onDataPulled(allData);
1082
Chenjie Yu32717c32018-10-20 23:54:48 -07001083 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001084 EXPECT_EQ(false, curInterval.hasBase);
1085 EXPECT_EQ(true, curInterval.hasValue);
1086 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001087 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001088}
1089
1090/*
1091 * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
1092 * change to false, and then true again. This is due to alarm delivered late.
1093 */
1094TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
1095 ValueMetric metric;
1096 metric.set_id(metricId);
1097 metric.set_bucket(ONE_MINUTE);
1098 metric.mutable_value_field()->set_field(tagId);
1099 metric.mutable_value_field()->add_child()->set_field(2);
1100 metric.set_condition(StringToId("SCREEN_ON"));
1101
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001102 UidMap uidMap;
1103 SimpleAtomMatcher atomMatcher;
1104 atomMatcher.set_atom_id(tagId);
1105 sp<EventMatcherWizard> eventMatcherWizard =
1106 new EventMatcherWizard({new SimpleLogMatchingTracker(
1107 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -07001108 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -07001109 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -07001110 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return());
1111 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1112
1113 EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
1114 // condition becomes true
1115 .WillOnce(Invoke([](int tagId, int64_t timeNs,
1116 vector<std::shared_ptr<LogEvent>>* data) {
1117 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001118 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001119 event->write(tagId);
1120 event->write(100);
1121 event->init();
1122 data->push_back(event);
1123 return true;
1124 }))
1125 // condition becomes false
1126 .WillOnce(Invoke([](int tagId, int64_t timeNs,
1127 vector<std::shared_ptr<LogEvent>>* data) {
1128 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001129 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001130 event->write(tagId);
1131 event->write(120);
1132 event->init();
1133 data->push_back(event);
1134 return true;
1135 }))
1136 // condition becomes true again
1137 .WillOnce(Invoke([](int tagId, int64_t timeNs,
1138 vector<std::shared_ptr<LogEvent>>* data) {
1139 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001140 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001141 event->write(tagId);
1142 event->write(130);
1143 event->init();
1144 data->push_back(event);
1145 return true;
1146 }));
1147
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001148 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1149 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -07001150 bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001151 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
1152
1153 // has one slice
1154 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001155 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001156 // startUpdated:false sum:0 start:100
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001157 EXPECT_EQ(true, curInterval.hasBase);
1158 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001159 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001160 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1161
1162 // pull on bucket boundary come late, condition change happens before it
1163 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
Chenjie Yu32717c32018-10-20 23:54:48 -07001164 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001165 EXPECT_EQ(false, curInterval.hasBase);
1166 EXPECT_EQ(true, curInterval.hasValue);
1167 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001168 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001169
1170 // condition changed to true again, before the pull alarm is delivered
1171 valueProducer.onConditionChanged(true, bucket2StartTimeNs + 25);
Chenjie Yu32717c32018-10-20 23:54:48 -07001172 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001173 EXPECT_EQ(true, curInterval.hasBase);
1174 EXPECT_EQ(130, curInterval.base.long_value);
1175 EXPECT_EQ(true, curInterval.hasValue);
1176 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001177 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001178
1179 // Now the alarm is delivered, but it is considered late, it has no effect
1180 vector<shared_ptr<LogEvent>> allData;
1181 allData.clear();
1182 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
1183 event->write(1);
1184 event->write(110);
1185 event->init();
1186 allData.push_back(event);
1187 valueProducer.onDataPulled(allData);
1188
Chenjie Yu32717c32018-10-20 23:54:48 -07001189 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001190 EXPECT_EQ(true, curInterval.hasBase);
1191 EXPECT_EQ(130, curInterval.base.long_value);
1192 EXPECT_EQ(true, curInterval.hasValue);
1193 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001194 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001195}
1196
Chenjie Yua0f02242018-07-06 16:14:34 -07001197TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
1198 ValueMetric metric;
1199 metric.set_id(metricId);
1200 metric.set_bucket(ONE_MINUTE);
1201 metric.mutable_value_field()->set_field(tagId);
1202 metric.mutable_value_field()->add_child()->set_field(2);
1203 metric.set_aggregation_type(ValueMetric::MIN);
1204
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001205 UidMap uidMap;
1206 SimpleAtomMatcher atomMatcher;
1207 atomMatcher.set_atom_id(tagId);
1208 sp<EventMatcherWizard> eventMatcherWizard =
1209 new EventMatcherWizard({new SimpleLogMatchingTracker(
1210 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001211 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1212 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1213
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001214 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1215 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1216 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001217
1218 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1219 event1->write(1);
1220 event1->write(10);
1221 event1->init();
1222 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1223 event2->write(1);
1224 event2->write(20);
1225 event2->init();
1226 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1227 // has one slice
1228 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001229 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001230 EXPECT_EQ(10, curInterval.value.long_value);
1231 EXPECT_EQ(true, curInterval.hasValue);
1232
1233 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1234
1235 // has one slice
1236 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001237 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001238 EXPECT_EQ(10, curInterval.value.long_value);
1239
1240 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1241 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1242 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001243 EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001244}
1245
1246TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
1247 ValueMetric metric;
1248 metric.set_id(metricId);
1249 metric.set_bucket(ONE_MINUTE);
1250 metric.mutable_value_field()->set_field(tagId);
1251 metric.mutable_value_field()->add_child()->set_field(2);
1252 metric.set_aggregation_type(ValueMetric::MAX);
1253
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001254 UidMap uidMap;
1255 SimpleAtomMatcher atomMatcher;
1256 atomMatcher.set_atom_id(tagId);
1257 sp<EventMatcherWizard> eventMatcherWizard =
1258 new EventMatcherWizard({new SimpleLogMatchingTracker(
1259 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001260 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1261 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1262
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001263 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1264 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1265 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001266
1267 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1268 event1->write(1);
1269 event1->write(10);
1270 event1->init();
1271 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1272 event2->write(1);
1273 event2->write(20);
1274 event2->init();
1275 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1276 // has one slice
1277 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001278 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001279 EXPECT_EQ(10, curInterval.value.long_value);
1280 EXPECT_EQ(true, curInterval.hasValue);
1281
1282 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1283
1284 // has one slice
1285 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001286 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001287 EXPECT_EQ(20, curInterval.value.long_value);
1288
1289 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1290 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1291 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001292 EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001293}
1294
1295TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
1296 ValueMetric metric;
1297 metric.set_id(metricId);
1298 metric.set_bucket(ONE_MINUTE);
1299 metric.mutable_value_field()->set_field(tagId);
1300 metric.mutable_value_field()->add_child()->set_field(2);
1301 metric.set_aggregation_type(ValueMetric::AVG);
1302
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001303 UidMap uidMap;
1304 SimpleAtomMatcher atomMatcher;
1305 atomMatcher.set_atom_id(tagId);
1306 sp<EventMatcherWizard> eventMatcherWizard =
1307 new EventMatcherWizard({new SimpleLogMatchingTracker(
1308 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001309 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1310 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1311
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001312 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1313 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1314 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001315
1316 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1317 event1->write(1);
1318 event1->write(10);
1319 event1->init();
1320 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1321 event2->write(1);
1322 event2->write(15);
1323 event2->init();
1324 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1325 // has one slice
1326 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1327 ValueMetricProducer::Interval curInterval;
Chenjie Yu32717c32018-10-20 23:54:48 -07001328 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001329 EXPECT_EQ(10, curInterval.value.long_value);
1330 EXPECT_EQ(true, curInterval.hasValue);
1331 EXPECT_EQ(1, curInterval.sampleSize);
1332
1333 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1334
1335 // has one slice
1336 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001337 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001338 EXPECT_EQ(25, curInterval.value.long_value);
1339 EXPECT_EQ(2, curInterval.sampleSize);
1340
1341 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1342 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1343 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001344 EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value - 12.5) < epsilon);
Chenjie Yua0f02242018-07-06 16:14:34 -07001345}
1346
1347TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
1348 ValueMetric metric;
1349 metric.set_id(metricId);
1350 metric.set_bucket(ONE_MINUTE);
1351 metric.mutable_value_field()->set_field(tagId);
1352 metric.mutable_value_field()->add_child()->set_field(2);
1353 metric.set_aggregation_type(ValueMetric::SUM);
1354
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001355 UidMap uidMap;
1356 SimpleAtomMatcher atomMatcher;
1357 atomMatcher.set_atom_id(tagId);
1358 sp<EventMatcherWizard> eventMatcherWizard =
1359 new EventMatcherWizard({new SimpleLogMatchingTracker(
1360 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001361 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1362 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1363
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001364 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1365 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1366 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001367
1368 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1369 event1->write(1);
1370 event1->write(10);
1371 event1->init();
1372 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1373 event2->write(1);
1374 event2->write(15);
1375 event2->init();
1376 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1377 // has one slice
1378 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001379 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001380 EXPECT_EQ(10, curInterval.value.long_value);
1381 EXPECT_EQ(true, curInterval.hasValue);
1382
1383 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1384
1385 // has one slice
1386 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001387 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001388 EXPECT_EQ(25, curInterval.value.long_value);
1389
1390 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1391 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1392 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001393 EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001394}
1395
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001396TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
Chenjie Yua0f02242018-07-06 16:14:34 -07001397 ValueMetric metric;
1398 metric.set_id(metricId);
1399 metric.set_bucket(ONE_MINUTE);
1400 metric.mutable_value_field()->set_field(tagId);
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001401 metric.mutable_value_field()->add_child()->set_field(2);
1402 metric.set_aggregation_type(ValueMetric::MIN);
1403 metric.set_use_diff(true);
Chenjie Yua0f02242018-07-06 16:14:34 -07001404
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001405 UidMap uidMap;
1406 SimpleAtomMatcher atomMatcher;
1407 atomMatcher.set_atom_id(tagId);
1408 sp<EventMatcherWizard> eventMatcherWizard =
1409 new EventMatcherWizard({new SimpleLogMatchingTracker(
1410 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001411 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yua0f02242018-07-06 16:14:34 -07001412 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1413
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001414 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1415 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1416 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001417
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001418 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1419 event1->write(1);
1420 event1->write(10);
1421 event1->init();
1422 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
1423 event2->write(1);
1424 event2->write(15);
1425 event2->init();
1426 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1427 // has one slice
Chenjie Yua0f02242018-07-06 16:14:34 -07001428 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001429 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001430 EXPECT_EQ(true, curInterval.hasBase);
1431 EXPECT_EQ(10, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001432 EXPECT_EQ(false, curInterval.hasValue);
1433
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001434 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Chenjie Yua0f02242018-07-06 16:14:34 -07001435
1436 // has one slice
1437 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001438 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001439 EXPECT_EQ(true, curInterval.hasValue);
1440 EXPECT_EQ(5, curInterval.value.long_value);
1441
1442 // no change in data.
1443 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
1444 event3->write(1);
1445 event3->write(15);
1446 event3->init();
1447 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
1448 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001449 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001450 EXPECT_EQ(true, curInterval.hasBase);
1451 EXPECT_EQ(15, curInterval.base.long_value);
1452 EXPECT_EQ(true, curInterval.hasValue);
1453
1454 shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
1455 event4->write(1);
1456 event4->write(15);
1457 event4->init();
1458 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
1459 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001460 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001461 EXPECT_EQ(true, curInterval.hasBase);
1462 EXPECT_EQ(15, curInterval.base.long_value);
1463 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yua0f02242018-07-06 16:14:34 -07001464
1465 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1466 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1467 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001468 EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001469}
1470
Chenjie Yu6736c892017-11-09 10:50:09 -08001471} // namespace statsd
1472} // namespace os
1473} // namespace android
1474#else
1475GTEST_LOG_(INFO) << "This test does nothing.\n";
1476#endif