blob: 9cfe3436ada7206441688c4f850806b22ab57ba9 [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 Yu0bd73db2018-12-16 07:37:04 -0800128 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu6736c892017-11-09 10:50:09 -0800129
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800130 UidMap uidMap;
131 SimpleAtomMatcher atomMatcher;
132 atomMatcher.set_atom_id(tagId);
133 sp<EventMatcherWizard> eventMatcherWizard =
134 new EventMatcherWizard({new SimpleLogMatchingTracker(
135 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800136 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700137 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700138 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
Chenjie Yu6736c892017-11-09 10:50:09 -0800139 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800140 EXPECT_CALL(*pullerManager, Pull(tagId, _))
141 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yue1361ed2018-07-23 17:33:09 -0700142 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);
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800221 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800222
223 UidMap uidMap;
224 SimpleAtomMatcher atomMatcher;
225 atomMatcher.set_atom_id(tagId);
226 auto keyValue = atomMatcher.add_field_value_matcher();
227 keyValue->set_field(1);
228 keyValue->set_eq_int(3);
229 sp<EventMatcherWizard> eventMatcherWizard =
230 new EventMatcherWizard({new SimpleLogMatchingTracker(
231 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
232 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
233 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
234 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
235 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800236 EXPECT_CALL(*pullerManager, Pull(tagId, _))
237 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800238 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);
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800318 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu021e2532018-05-16 12:23:07 -0700319
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800320 UidMap uidMap;
321 SimpleAtomMatcher atomMatcher;
322 atomMatcher.set_atom_id(tagId);
323 sp<EventMatcherWizard> eventMatcherWizard =
324 new EventMatcherWizard({new SimpleLogMatchingTracker(
325 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700326 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700327 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700328 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
329 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800330 EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
Chenjie Yu021e2532018-05-16 12:23:07 -0700331
332 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800333 logEventMatcherIndex, eventMatcherWizard, tagId,
334 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700335
336 vector<shared_ptr<LogEvent>> allData;
337 allData.clear();
338 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
339 event->write(tagId);
340 event->write(11);
341 event->init();
342 allData.push_back(event);
343
344 valueProducer.onDataPulled(allData);
345 // has one slice
346 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700347 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu021e2532018-05-16 12:23:07 -0700348
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700349 EXPECT_EQ(true, curInterval.hasBase);
350 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700351 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700352 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
353
354 allData.clear();
355 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
356 event->write(tagId);
357 event->write(10);
358 event->init();
359 allData.push_back(event);
360 valueProducer.onDataPulled(allData);
361 // has one slice
362 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700363 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700364 EXPECT_EQ(true, curInterval.hasBase);
365 EXPECT_EQ(10, curInterval.base.long_value);
366 EXPECT_EQ(true, curInterval.hasValue);
367 EXPECT_EQ(10, curInterval.value.long_value);
368 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700369
370 allData.clear();
371 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
372 event->write(tagId);
373 event->write(36);
374 event->init();
375 allData.push_back(event);
376 valueProducer.onDataPulled(allData);
377 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700378 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700379 EXPECT_EQ(true, curInterval.hasBase);
380 EXPECT_EQ(36, curInterval.base.long_value);
381 EXPECT_EQ(true, curInterval.hasValue);
382 EXPECT_EQ(26, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700383 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700384 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700385 EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700386}
387
388/*
389 * Tests pulled atoms with no conditions and take zero value after reset
390 */
391TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
392 ValueMetric metric;
393 metric.set_id(metricId);
394 metric.set_bucket(ONE_MINUTE);
395 metric.mutable_value_field()->set_field(tagId);
396 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800397 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu021e2532018-05-16 12:23:07 -0700398
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800399 UidMap uidMap;
400 SimpleAtomMatcher atomMatcher;
401 atomMatcher.set_atom_id(tagId);
402 sp<EventMatcherWizard> eventMatcherWizard =
403 new EventMatcherWizard({new SimpleLogMatchingTracker(
404 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700405 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700406 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700407 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
408 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800409 EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
Chenjie Yu021e2532018-05-16 12:23:07 -0700410
411 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800412 logEventMatcherIndex, eventMatcherWizard, tagId,
413 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700414
415 vector<shared_ptr<LogEvent>> allData;
416 allData.clear();
417 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
418 event->write(tagId);
419 event->write(11);
420 event->init();
421 allData.push_back(event);
422
423 valueProducer.onDataPulled(allData);
424 // has one slice
425 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700426 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu021e2532018-05-16 12:23:07 -0700427
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700428 EXPECT_EQ(true, curInterval.hasBase);
429 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700430 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700431 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
432
433 allData.clear();
434 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
435 event->write(tagId);
436 event->write(10);
437 event->init();
438 allData.push_back(event);
439 valueProducer.onDataPulled(allData);
440 // has one slice
441 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700442 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700443 EXPECT_EQ(true, curInterval.hasBase);
444 EXPECT_EQ(10, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700445 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu021e2532018-05-16 12:23:07 -0700446 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
447
448 allData.clear();
449 event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
450 event->write(tagId);
451 event->write(36);
452 event->init();
453 allData.push_back(event);
454 valueProducer.onDataPulled(allData);
455 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700456 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700457 EXPECT_EQ(true, curInterval.hasBase);
458 EXPECT_EQ(36, curInterval.base.long_value);
459 EXPECT_EQ(true, curInterval.hasValue);
460 EXPECT_EQ(26, curInterval.value.long_value);
461 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700462}
463
464/*
Chenjie Yu6736c892017-11-09 10:50:09 -0800465 * Test pulled event with non sliced condition.
466 */
467TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
Chenjie Yu6736c892017-11-09 10:50:09 -0800468 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800469 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800470 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800471 metric.mutable_value_field()->set_field(tagId);
472 metric.mutable_value_field()->add_child()->set_field(2);
Yangster-mac94e197c2018-01-02 16:03:03 -0800473 metric.set_condition(StringToId("SCREEN_ON"));
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800474 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu6736c892017-11-09 10:50:09 -0800475
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800476 UidMap uidMap;
477 SimpleAtomMatcher atomMatcher;
478 atomMatcher.set_atom_id(tagId);
479 sp<EventMatcherWizard> eventMatcherWizard =
480 new EventMatcherWizard({new SimpleLogMatchingTracker(
481 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800482 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700483 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700484 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
Chenjie Yu6736c892017-11-09 10:50:09 -0800485 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
486
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800487 EXPECT_CALL(*pullerManager, Pull(tagId, _))
488 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yue1361ed2018-07-23 17:33:09 -0700489 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700490 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800491 event->write(tagId);
Yao Chenb3561512017-11-21 18:07:17 -0800492 event->write(100);
493 event->init();
494 data->push_back(event);
495 return true;
496 }))
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800497 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Yao Chenb3561512017-11-21 18:07:17 -0800498 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700499 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800500 event->write(tagId);
Yao Chenb3561512017-11-21 18:07:17 -0800501 event->write(120);
502 event->init();
503 data->push_back(event);
504 return true;
505 }));
Chenjie Yu6736c892017-11-09 10:50:09 -0800506
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800507 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
508 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700509 bucketStartTimeNs, pullerManager);
Chenjie Yua7259ab2017-12-10 08:31:05 -0800510 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
Chenjie Yu6736c892017-11-09 10:50:09 -0800511
512 // has one slice
513 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700514 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700515 // startUpdated:false sum:0 start:100
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700516 EXPECT_EQ(true, curInterval.hasBase);
517 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -0700518 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6736c892017-11-09 10:50:09 -0800519 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
520
521 vector<shared_ptr<LogEvent>> allData;
522 allData.clear();
523 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Yao Chen80235402017-11-13 20:42:25 -0800524 event->write(1);
525 event->write(110);
Chenjie Yu6736c892017-11-09 10:50:09 -0800526 event->init();
527 allData.push_back(event);
528 valueProducer.onDataPulled(allData);
529
530 // has one slice
531 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700532 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700533 EXPECT_EQ(true, curInterval.hasBase);
534 EXPECT_EQ(110, curInterval.base.long_value);
535 EXPECT_EQ(true, curInterval.hasValue);
536 EXPECT_EQ(10, curInterval.value.long_value);
537 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6736c892017-11-09 10:50:09 -0800538
539 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
540
541 // has one slice
542 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700543 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700544 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yua0f02242018-07-06 16:14:34 -0700545 EXPECT_EQ(10, curInterval.value.long_value);
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700546 EXPECT_EQ(false, curInterval.hasBase);
Chenjie Yu6736c892017-11-09 10:50:09 -0800547}
548
David Chen27785a82018-01-19 17:06:45 -0800549TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
550 ValueMetric metric;
551 metric.set_id(metricId);
552 metric.set_bucket(ONE_MINUTE);
553 metric.mutable_value_field()->set_field(tagId);
554 metric.mutable_value_field()->add_child()->set_field(2);
555
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800556 UidMap uidMap;
557 SimpleAtomMatcher atomMatcher;
558 atomMatcher.set_atom_id(tagId);
559 sp<EventMatcherWizard> eventMatcherWizard =
560 new EventMatcherWizard({new SimpleLogMatchingTracker(
561 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen27785a82018-01-19 17:06:45 -0800562 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700563 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800564 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
565 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
566 pullerManager);
David Chen27785a82018-01-19 17:06:45 -0800567
568 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
569 event1->write(1);
570 event1->write(10);
571 event1->init();
572 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
573 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
574
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700575 valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
David Chen27785a82018-01-19 17:06:45 -0800576 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700577 EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800578
579 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
580 event2->write(1);
581 event2->write(10);
582 event2->init();
583 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
584 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700585 EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800586
587 // Next value should create a new bucket.
588 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
589 event3->write(1);
590 event3->write(10);
591 event3->init();
592 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
593 EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Yangster-macb142cc82018-03-30 15:22:08 -0700594 EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800595}
596
597TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
598 ValueMetric metric;
599 metric.set_id(metricId);
600 metric.set_bucket(ONE_MINUTE);
601 metric.mutable_value_field()->set_field(tagId);
602 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800603 metric.set_max_pull_delay_sec(INT_MAX);
David Chen27785a82018-01-19 17:06:45 -0800604
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800605 UidMap uidMap;
606 SimpleAtomMatcher atomMatcher;
607 atomMatcher.set_atom_id(tagId);
608 sp<EventMatcherWizard> eventMatcherWizard =
609 new EventMatcherWizard({new SimpleLogMatchingTracker(
610 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen27785a82018-01-19 17:06:45 -0800611 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700612 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700613 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
David Chen27785a82018-01-19 17:06:45 -0800614 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800615 EXPECT_CALL(*pullerManager, Pull(tagId, _))
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700616 .WillOnce(Return(true))
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800617 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
David Chen27785a82018-01-19 17:06:45 -0800618 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700619 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
David Chen27785a82018-01-19 17:06:45 -0800620 event->write(tagId);
621 event->write(120);
622 event->init();
623 data->push_back(event);
624 return true;
625 }));
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800626 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
627 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700628 bucketStartTimeNs, pullerManager);
David Chen27785a82018-01-19 17:06:45 -0800629
630 vector<shared_ptr<LogEvent>> allData;
631 allData.clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700632 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
David Chen27785a82018-01-19 17:06:45 -0800633 event->write(tagId);
634 event->write(100);
635 event->init();
636 allData.push_back(event);
637
638 valueProducer.onDataPulled(allData);
639 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
640
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700641 valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
David Chen27785a82018-01-19 17:06:45 -0800642 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700643 EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
Chenjie Yucd1b7972019-01-16 20:38:15 -0800644 EXPECT_EQ(20L,
645 valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
David Chen27785a82018-01-19 17:06:45 -0800646
647 allData.clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700648 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
David Chen27785a82018-01-19 17:06:45 -0800649 event->write(tagId);
650 event->write(150);
651 event->init();
652 allData.push_back(event);
653 valueProducer.onDataPulled(allData);
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700654 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
655 EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
Chenjie Yucd1b7972019-01-16 20:38:15 -0800656 EXPECT_EQ(20L,
657 valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
658}
659
660TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
661 ValueMetric metric;
662 metric.set_id(metricId);
663 metric.set_bucket(ONE_MINUTE);
664 metric.mutable_value_field()->set_field(tagId);
665 metric.mutable_value_field()->add_child()->set_field(2);
666 metric.set_max_pull_delay_sec(INT_MAX);
667 metric.set_split_bucket_for_app_upgrade(false);
668
669 UidMap uidMap;
670 SimpleAtomMatcher atomMatcher;
671 atomMatcher.set_atom_id(tagId);
672 sp<EventMatcherWizard> eventMatcherWizard =
673 new EventMatcherWizard({new SimpleLogMatchingTracker(
674 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
675 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
676 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
677 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
678 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
679 EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
680 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
681 eventMatcherWizard, tagId, bucketStartTimeNs,
682 bucketStartTimeNs, pullerManager);
683
684 vector<shared_ptr<LogEvent>> allData;
685 allData.clear();
686 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
687 event->write(tagId);
688 event->write(100);
689 event->init();
690 allData.push_back(event);
691
692 valueProducer.onDataPulled(allData);
693 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
694
695 valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
696 EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
697 EXPECT_EQ(bucketStartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
David Chen27785a82018-01-19 17:06:45 -0800698}
699
David Chen092a5a92018-05-15 17:50:32 -0700700TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
701 ValueMetric metric;
702 metric.set_id(metricId);
703 metric.set_bucket(ONE_MINUTE);
704 metric.mutable_value_field()->set_field(tagId);
705 metric.mutable_value_field()->add_child()->set_field(2);
706 metric.set_condition(StringToId("SCREEN_ON"));
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800707 metric.set_max_pull_delay_sec(INT_MAX);
David Chen092a5a92018-05-15 17:50:32 -0700708
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800709 UidMap uidMap;
710 SimpleAtomMatcher atomMatcher;
711 atomMatcher.set_atom_id(tagId);
712 sp<EventMatcherWizard> eventMatcherWizard =
713 new EventMatcherWizard({new SimpleLogMatchingTracker(
714 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
David Chen092a5a92018-05-15 17:50:32 -0700715 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700716 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
David Chen092a5a92018-05-15 17:50:32 -0700717 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
718 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800719 EXPECT_CALL(*pullerManager, Pull(tagId, _))
720 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
David Chen092a5a92018-05-15 17:50:32 -0700721 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700722 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
David Chen092a5a92018-05-15 17:50:32 -0700723 event->write(tagId);
724 event->write(100);
725 event->init();
726 data->push_back(event);
727 return true;
728 }))
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800729 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
David Chen092a5a92018-05-15 17:50:32 -0700730 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700731 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
David Chen092a5a92018-05-15 17:50:32 -0700732 event->write(tagId);
733 event->write(120);
734 event->init();
735 data->push_back(event);
736 return true;
737 }));
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800738 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
739 eventMatcherWizard, tagId, bucketStartTimeNs,
David Chen092a5a92018-05-15 17:50:32 -0700740 bucketStartTimeNs, pullerManager);
David Chen092a5a92018-05-15 17:50:32 -0700741 valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
742
743 valueProducer.onConditionChanged(false, bucket2StartTimeNs-100);
744 EXPECT_FALSE(valueProducer.mCondition);
745
746 valueProducer.notifyAppUpgrade(bucket2StartTimeNs-50, "ANY.APP", 1, 1);
747 // Expect one full buckets already done and starting a partial bucket.
748 EXPECT_EQ(bucket2StartTimeNs-50, valueProducer.mCurrentBucketStartTimeNs);
749 EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
750 EXPECT_EQ(bucketStartTimeNs, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
Chenjie Yu32717c32018-10-20 23:54:48 -0700751 EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
David Chen092a5a92018-05-15 17:50:32 -0700752 EXPECT_FALSE(valueProducer.mCondition);
753}
754
Chenjie Yu6736c892017-11-09 10:50:09 -0800755TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
Chenjie Yu6736c892017-11-09 10:50:09 -0800756 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800757 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800758 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800759 metric.mutable_value_field()->set_field(tagId);
760 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu6736c892017-11-09 10:50:09 -0800761
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800762 UidMap uidMap;
763 SimpleAtomMatcher atomMatcher;
764 atomMatcher.set_atom_id(tagId);
765 sp<EventMatcherWizard> eventMatcherWizard =
766 new EventMatcherWizard({new SimpleLogMatchingTracker(
767 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6736c892017-11-09 10:50:09 -0800768 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700769 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6736c892017-11-09 10:50:09 -0800770
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800771 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
772 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
773 pullerManager);
Chenjie Yu6736c892017-11-09 10:50:09 -0800774
775 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
Yao Chen80235402017-11-13 20:42:25 -0800776 event1->write(1);
777 event1->write(10);
Chenjie Yu6736c892017-11-09 10:50:09 -0800778 event1->init();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800779 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
Yao Chen80235402017-11-13 20:42:25 -0800780 event2->write(1);
781 event2->write(20);
Chenjie Yu6736c892017-11-09 10:50:09 -0800782 event2->init();
Chenjie Yua7259ab2017-12-10 08:31:05 -0800783 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
Chenjie Yu6736c892017-11-09 10:50:09 -0800784 // has one slice
785 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700786 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700787 EXPECT_EQ(10, curInterval.value.long_value);
788 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yu6736c892017-11-09 10:50:09 -0800789
Chenjie Yua7259ab2017-12-10 08:31:05 -0800790 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Chenjie Yu6736c892017-11-09 10:50:09 -0800791
792 // has one slice
793 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700794 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700795 EXPECT_EQ(30, curInterval.value.long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800796
Yangsterf2bee6f2017-11-29 12:01:05 -0800797 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
Chenjie Yu6736c892017-11-09 10:50:09 -0800798 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
799 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700800 EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6736c892017-11-09 10:50:09 -0800801}
802
Chenjie Yu021e2532018-05-16 12:23:07 -0700803TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
804 ValueMetric metric;
805 metric.set_id(metricId);
806 metric.set_bucket(ONE_MINUTE);
807 metric.mutable_value_field()->set_field(tagId);
808 metric.mutable_value_field()->add_child()->set_field(2);
809
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800810 UidMap uidMap;
811 SimpleAtomMatcher atomMatcher;
812 atomMatcher.set_atom_id(tagId);
813 sp<EventMatcherWizard> eventMatcherWizard =
814 new EventMatcherWizard({new SimpleLogMatchingTracker(
815 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu021e2532018-05-16 12:23:07 -0700816 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700817 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu021e2532018-05-16 12:23:07 -0700818
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800819 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
820 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
821 pullerManager);
Chenjie Yu021e2532018-05-16 12:23:07 -0700822
823 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
824 event1->write(1);
825 event1->write(10);
826 event1->init();
827 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
828 // has 1 slice
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700829 EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu021e2532018-05-16 12:23:07 -0700830
831 valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
832 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
833 event2->write(1);
834 event2->write(20);
835 event2->init();
836 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
837
838 // has one slice
839 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700840 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
841 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700842 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700843
844 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
845 event3->write(1);
846 event3->write(30);
847 event3->init();
848 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
849
850 // has one slice
851 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700852 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700853 EXPECT_EQ(50, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700854
855 valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
856 shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 40);
857 event4->write(1);
858 event4->write(40);
859 event4->init();
860 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
861
862 // has one slice
863 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700864 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -0700865 EXPECT_EQ(50, curInterval.value.long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700866
867 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
868 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
869 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700870 EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu021e2532018-05-16 12:23:07 -0700871}
872
Bookatzde1b55622017-12-14 18:38:27 -0800873TEST(ValueMetricProducerTest, TestAnomalyDetection) {
Yangster-mac932ecec2018-02-01 10:23:52 -0800874 sp<AlarmMonitor> alarmMonitor;
Bookatzde1b55622017-12-14 18:38:27 -0800875 Alert alert;
Yangster-mac94e197c2018-01-02 16:03:03 -0800876 alert.set_id(101);
877 alert.set_metric_id(metricId);
Bookatzde1b55622017-12-14 18:38:27 -0800878 alert.set_trigger_if_sum_gt(130);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800879 alert.set_num_buckets(2);
Bookatz1bf94382018-01-04 11:43:20 -0800880 const int32_t refPeriodSec = 3;
881 alert.set_refractory_period_secs(refPeriodSec);
Bookatzde1b55622017-12-14 18:38:27 -0800882
883 ValueMetric metric;
Yangster-mac94e197c2018-01-02 16:03:03 -0800884 metric.set_id(metricId);
Yangster-macb8144812018-01-04 10:56:23 -0800885 metric.set_bucket(ONE_MINUTE);
Yangster-maca7fb12d2018-01-03 17:17:20 -0800886 metric.mutable_value_field()->set_field(tagId);
887 metric.mutable_value_field()->add_child()->set_field(2);
Bookatzde1b55622017-12-14 18:38:27 -0800888
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800889 UidMap uidMap;
890 SimpleAtomMatcher atomMatcher;
891 atomMatcher.set_atom_id(tagId);
892 sp<EventMatcherWizard> eventMatcherWizard =
893 new EventMatcherWizard({new SimpleLogMatchingTracker(
894 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Bookatzde1b55622017-12-14 18:38:27 -0800895 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700896 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Bookatzde1b55622017-12-14 18:38:27 -0800897 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800898 logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
899 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
yro59cc24d2018-02-13 20:17:32 -0800900
Yangster-mac932ecec2018-02-01 10:23:52 -0800901 sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
Bookatzde1b55622017-12-14 18:38:27 -0800902
903
904 shared_ptr<LogEvent> event1
905 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1 * NS_PER_SEC);
906 event1->write(161);
907 event1->write(10); // value of interest
908 event1->init();
909 shared_ptr<LogEvent> event2
910 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 + NS_PER_SEC);
911 event2->write(162);
912 event2->write(20); // value of interest
913 event2->init();
914 shared_ptr<LogEvent> event3
915 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC);
916 event3->write(163);
917 event3->write(130); // value of interest
918 event3->init();
919 shared_ptr<LogEvent> event4
920 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC);
921 event4->write(35);
922 event4->write(1); // value of interest
923 event4->init();
924 shared_ptr<LogEvent> event5
925 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC);
926 event5->write(45);
927 event5->write(150); // value of interest
928 event5->init();
929 shared_ptr<LogEvent> event6
930 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC);
931 event6->write(25);
932 event6->write(160); // value of interest
933 event6->init();
934
935 // Two events in bucket #0.
936 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
937 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Bookatz1bf94382018-01-04 11:43:20 -0800938 // Value sum == 30 <= 130.
Yangster-mac93694462018-01-22 20:49:31 -0800939 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
Bookatzde1b55622017-12-14 18:38:27 -0800940
941 // One event in bucket #2. No alarm as bucket #0 is trashed out.
942 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
Bookatz1bf94382018-01-04 11:43:20 -0800943 // Value sum == 130 <= 130.
Yangster-mac93694462018-01-22 20:49:31 -0800944 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
Bookatzde1b55622017-12-14 18:38:27 -0800945
946 // Three events in bucket #3.
947 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
948 // Anomaly at event 4 since Value sum == 131 > 130!
Yangster-mac93694462018-01-22 20:49:31 -0800949 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700950 std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800951 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event5);
952 // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
Yangster-mac93694462018-01-22 20:49:31 -0800953 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700954 std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800955
956 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event6);
957 // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
Yangster-mac93694462018-01-22 20:49:31 -0800958 EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
Bookatz6bf98252018-03-14 10:44:24 -0700959 std::ceil(1.0 * event6->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
Bookatzde1b55622017-12-14 18:38:27 -0800960}
961
Chenjie Yu6d370f42018-03-25 14:57:30 -0700962// Test value metric no condition, the pull on bucket boundary come in time and too late
963TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
964 ValueMetric metric;
965 metric.set_id(metricId);
966 metric.set_bucket(ONE_MINUTE);
967 metric.mutable_value_field()->set_field(tagId);
968 metric.mutable_value_field()->add_child()->set_field(2);
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800969 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu6d370f42018-03-25 14:57:30 -0700970
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800971 UidMap uidMap;
972 SimpleAtomMatcher atomMatcher;
973 atomMatcher.set_atom_id(tagId);
974 sp<EventMatcherWizard> eventMatcherWizard =
975 new EventMatcherWizard({new SimpleLogMatchingTracker(
976 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -0700977 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -0700978 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -0700979 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
980 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800981 EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
Chenjie Yu6d370f42018-03-25 14:57:30 -0700982
983 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800984 logEventMatcherIndex, eventMatcherWizard, tagId,
985 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -0700986
987 vector<shared_ptr<LogEvent>> allData;
988 // pull 1
989 allData.clear();
990 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
991 event->write(tagId);
992 event->write(11);
993 event->init();
994 allData.push_back(event);
995
996 valueProducer.onDataPulled(allData);
997 // has one slice
998 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -0700999 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yu6d370f42018-03-25 14:57:30 -07001000
Chenjie Yua0f02242018-07-06 16:14:34 -07001001 // startUpdated:true sum:0 start:11
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001002 EXPECT_EQ(true, curInterval.hasBase);
1003 EXPECT_EQ(11, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001004 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001005 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001006
1007 // pull 2 at correct time
1008 allData.clear();
1009 event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
1010 event->write(tagId);
1011 event->write(23);
1012 event->init();
1013 allData.push_back(event);
1014 valueProducer.onDataPulled(allData);
1015 // has one slice
1016 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001017 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001018 // tartUpdated:false sum:12
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001019 EXPECT_EQ(true, curInterval.hasBase);
1020 EXPECT_EQ(23, curInterval.base.long_value);
1021 EXPECT_EQ(true, curInterval.hasValue);
1022 EXPECT_EQ(12, curInterval.value.long_value);
1023 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001024
1025 // pull 3 come late.
1026 // The previous bucket gets closed with error. (Has start value 23, no ending)
1027 // Another bucket gets closed with error. (No start, but ending with 36)
1028 // The new bucket is back to normal.
1029 allData.clear();
1030 event = make_shared<LogEvent>(tagId, bucket6StartTimeNs + 1);
1031 event->write(tagId);
1032 event->write(36);
1033 event->init();
1034 allData.push_back(event);
1035 valueProducer.onDataPulled(allData);
1036 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001037 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001038 // startUpdated:false sum:12
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001039 EXPECT_EQ(true, curInterval.hasBase);
1040 EXPECT_EQ(36, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001041 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001042 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001043 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001044 EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001045}
1046
1047/*
1048 * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
1049 * was delivered late.
1050 */
1051TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
1052 ValueMetric metric;
1053 metric.set_id(metricId);
1054 metric.set_bucket(ONE_MINUTE);
1055 metric.mutable_value_field()->set_field(tagId);
1056 metric.mutable_value_field()->add_child()->set_field(2);
1057 metric.set_condition(StringToId("SCREEN_ON"));
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001058 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001059
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001060 UidMap uidMap;
1061 SimpleAtomMatcher atomMatcher;
1062 atomMatcher.set_atom_id(tagId);
1063 sp<EventMatcherWizard> eventMatcherWizard =
1064 new EventMatcherWizard({new SimpleLogMatchingTracker(
1065 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -07001066 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -07001067 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -07001068 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1069 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1070
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001071 EXPECT_CALL(*pullerManager, Pull(tagId, _))
Chenjie Yu6d370f42018-03-25 14:57:30 -07001072 // condition becomes true
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001073 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu6d370f42018-03-25 14:57:30 -07001074 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001075 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001076 event->write(tagId);
1077 event->write(100);
1078 event->init();
1079 data->push_back(event);
1080 return true;
1081 }))
1082 // condition becomes false
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001083 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu6d370f42018-03-25 14:57:30 -07001084 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001085 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001086 event->write(tagId);
1087 event->write(120);
1088 event->init();
1089 data->push_back(event);
1090 return true;
1091 }));
1092
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001093 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1094 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -07001095 bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001096 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
1097
1098 // has one slice
1099 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001100 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001101 EXPECT_EQ(true, curInterval.hasBase);
1102 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001103 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001104 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1105
1106 // pull on bucket boundary come late, condition change happens before it
1107 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
Chenjie Yu32717c32018-10-20 23:54:48 -07001108 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001109 EXPECT_EQ(false, curInterval.hasBase);
1110 EXPECT_EQ(true, curInterval.hasValue);
1111 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001112 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001113
1114 // Now the alarm is delivered.
1115 // since the condition turned to off before this pull finish, it has no effect
1116 vector<shared_ptr<LogEvent>> allData;
1117 allData.clear();
1118 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 30);
1119 event->write(1);
1120 event->write(110);
1121 event->init();
1122 allData.push_back(event);
1123 valueProducer.onDataPulled(allData);
1124
Chenjie Yu32717c32018-10-20 23:54:48 -07001125 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001126 EXPECT_EQ(false, curInterval.hasBase);
1127 EXPECT_EQ(true, curInterval.hasValue);
1128 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001129 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001130}
1131
1132/*
1133 * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
1134 * change to false, and then true again. This is due to alarm delivered late.
1135 */
1136TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
1137 ValueMetric metric;
1138 metric.set_id(metricId);
1139 metric.set_bucket(ONE_MINUTE);
1140 metric.mutable_value_field()->set_field(tagId);
1141 metric.mutable_value_field()->add_child()->set_field(2);
1142 metric.set_condition(StringToId("SCREEN_ON"));
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001143 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001144
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001145 UidMap uidMap;
1146 SimpleAtomMatcher atomMatcher;
1147 atomMatcher.set_atom_id(tagId);
1148 sp<EventMatcherWizard> eventMatcherWizard =
1149 new EventMatcherWizard({new SimpleLogMatchingTracker(
1150 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yu6d370f42018-03-25 14:57:30 -07001151 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yue2219202018-06-08 10:07:51 -07001152 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
Chenjie Yu6d370f42018-03-25 14:57:30 -07001153 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return());
1154 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1155
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001156 EXPECT_CALL(*pullerManager, Pull(tagId, _))
Chenjie Yu6d370f42018-03-25 14:57:30 -07001157 // condition becomes true
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001158 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu6d370f42018-03-25 14:57:30 -07001159 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001160 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001161 event->write(tagId);
1162 event->write(100);
1163 event->init();
1164 data->push_back(event);
1165 return true;
1166 }))
1167 // condition becomes false
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001168 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu6d370f42018-03-25 14:57:30 -07001169 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001170 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001171 event->write(tagId);
1172 event->write(120);
1173 event->init();
1174 data->push_back(event);
1175 return true;
1176 }))
1177 // condition becomes true again
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001178 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yu6d370f42018-03-25 14:57:30 -07001179 data->clear();
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001180 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001181 event->write(tagId);
1182 event->write(130);
1183 event->init();
1184 data->push_back(event);
1185 return true;
1186 }));
1187
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001188 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1189 eventMatcherWizard, tagId, bucketStartTimeNs,
Yangster-mac15f6bbc2018-04-08 11:52:26 -07001190 bucketStartTimeNs, pullerManager);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001191 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
1192
1193 // has one slice
1194 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001195 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001196 // startUpdated:false sum:0 start:100
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001197 EXPECT_EQ(true, curInterval.hasBase);
1198 EXPECT_EQ(100, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001199 EXPECT_EQ(false, curInterval.hasValue);
Chenjie Yu6d370f42018-03-25 14:57:30 -07001200 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1201
1202 // pull on bucket boundary come late, condition change happens before it
1203 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
Chenjie Yu32717c32018-10-20 23:54:48 -07001204 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001205 EXPECT_EQ(false, curInterval.hasBase);
1206 EXPECT_EQ(true, curInterval.hasValue);
1207 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001208 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001209
1210 // condition changed to true again, before the pull alarm is delivered
1211 valueProducer.onConditionChanged(true, bucket2StartTimeNs + 25);
Chenjie Yu32717c32018-10-20 23:54:48 -07001212 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001213 EXPECT_EQ(true, curInterval.hasBase);
1214 EXPECT_EQ(130, curInterval.base.long_value);
1215 EXPECT_EQ(true, curInterval.hasValue);
1216 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001217 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001218
1219 // Now the alarm is delivered, but it is considered late, it has no effect
1220 vector<shared_ptr<LogEvent>> allData;
1221 allData.clear();
1222 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
1223 event->write(1);
1224 event->write(110);
1225 event->init();
1226 allData.push_back(event);
1227 valueProducer.onDataPulled(allData);
1228
Chenjie Yu32717c32018-10-20 23:54:48 -07001229 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001230 EXPECT_EQ(true, curInterval.hasBase);
1231 EXPECT_EQ(130, curInterval.base.long_value);
1232 EXPECT_EQ(true, curInterval.hasValue);
1233 EXPECT_EQ(20, curInterval.value.long_value);
Chenjie Yuae63b0a2018-04-10 14:59:31 -07001234 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
Chenjie Yu6d370f42018-03-25 14:57:30 -07001235}
1236
Chenjie Yua0f02242018-07-06 16:14:34 -07001237TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
1238 ValueMetric metric;
1239 metric.set_id(metricId);
1240 metric.set_bucket(ONE_MINUTE);
1241 metric.mutable_value_field()->set_field(tagId);
1242 metric.mutable_value_field()->add_child()->set_field(2);
1243 metric.set_aggregation_type(ValueMetric::MIN);
1244
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001245 UidMap uidMap;
1246 SimpleAtomMatcher atomMatcher;
1247 atomMatcher.set_atom_id(tagId);
1248 sp<EventMatcherWizard> eventMatcherWizard =
1249 new EventMatcherWizard({new SimpleLogMatchingTracker(
1250 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001251 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1252 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1253
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001254 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1255 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1256 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001257
1258 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1259 event1->write(1);
1260 event1->write(10);
1261 event1->init();
1262 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1263 event2->write(1);
1264 event2->write(20);
1265 event2->init();
1266 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1267 // has one slice
1268 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001269 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001270 EXPECT_EQ(10, curInterval.value.long_value);
1271 EXPECT_EQ(true, curInterval.hasValue);
1272
1273 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1274
1275 // has one slice
1276 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001277 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001278 EXPECT_EQ(10, curInterval.value.long_value);
1279
1280 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1281 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1282 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001283 EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001284}
1285
1286TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
1287 ValueMetric metric;
1288 metric.set_id(metricId);
1289 metric.set_bucket(ONE_MINUTE);
1290 metric.mutable_value_field()->set_field(tagId);
1291 metric.mutable_value_field()->add_child()->set_field(2);
1292 metric.set_aggregation_type(ValueMetric::MAX);
1293
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001294 UidMap uidMap;
1295 SimpleAtomMatcher atomMatcher;
1296 atomMatcher.set_atom_id(tagId);
1297 sp<EventMatcherWizard> eventMatcherWizard =
1298 new EventMatcherWizard({new SimpleLogMatchingTracker(
1299 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001300 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1301 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1302
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001303 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1304 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1305 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001306
1307 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1308 event1->write(1);
1309 event1->write(10);
1310 event1->init();
1311 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1312 event2->write(1);
1313 event2->write(20);
1314 event2->init();
1315 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1316 // has one slice
1317 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001318 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001319 EXPECT_EQ(10, curInterval.value.long_value);
1320 EXPECT_EQ(true, curInterval.hasValue);
1321
1322 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1323
1324 // has one slice
1325 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001326 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001327 EXPECT_EQ(20, curInterval.value.long_value);
1328
1329 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1330 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1331 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001332 EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001333}
1334
1335TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
1336 ValueMetric metric;
1337 metric.set_id(metricId);
1338 metric.set_bucket(ONE_MINUTE);
1339 metric.mutable_value_field()->set_field(tagId);
1340 metric.mutable_value_field()->add_child()->set_field(2);
1341 metric.set_aggregation_type(ValueMetric::AVG);
1342
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001343 UidMap uidMap;
1344 SimpleAtomMatcher atomMatcher;
1345 atomMatcher.set_atom_id(tagId);
1346 sp<EventMatcherWizard> eventMatcherWizard =
1347 new EventMatcherWizard({new SimpleLogMatchingTracker(
1348 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001349 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1350 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1351
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001352 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1353 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1354 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001355
1356 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1357 event1->write(1);
1358 event1->write(10);
1359 event1->init();
1360 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1361 event2->write(1);
1362 event2->write(15);
1363 event2->init();
1364 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1365 // has one slice
1366 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1367 ValueMetricProducer::Interval curInterval;
Chenjie Yu32717c32018-10-20 23:54:48 -07001368 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001369 EXPECT_EQ(10, curInterval.value.long_value);
1370 EXPECT_EQ(true, curInterval.hasValue);
1371 EXPECT_EQ(1, curInterval.sampleSize);
1372
1373 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1374
1375 // has one slice
1376 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001377 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001378 EXPECT_EQ(25, curInterval.value.long_value);
1379 EXPECT_EQ(2, curInterval.sampleSize);
1380
1381 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1382 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1383 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001384 EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value - 12.5) < epsilon);
Chenjie Yua0f02242018-07-06 16:14:34 -07001385}
1386
1387TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
1388 ValueMetric metric;
1389 metric.set_id(metricId);
1390 metric.set_bucket(ONE_MINUTE);
1391 metric.mutable_value_field()->set_field(tagId);
1392 metric.mutable_value_field()->add_child()->set_field(2);
1393 metric.set_aggregation_type(ValueMetric::SUM);
1394
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001395 UidMap uidMap;
1396 SimpleAtomMatcher atomMatcher;
1397 atomMatcher.set_atom_id(tagId);
1398 sp<EventMatcherWizard> eventMatcherWizard =
1399 new EventMatcherWizard({new SimpleLogMatchingTracker(
1400 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001401 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1402 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1403
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001404 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1405 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1406 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001407
1408 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1409 event1->write(1);
1410 event1->write(10);
1411 event1->init();
1412 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
1413 event2->write(1);
1414 event2->write(15);
1415 event2->init();
1416 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1417 // has one slice
1418 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001419 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001420 EXPECT_EQ(10, curInterval.value.long_value);
1421 EXPECT_EQ(true, curInterval.hasValue);
1422
1423 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
1424
1425 // has one slice
1426 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001427 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yua0f02242018-07-06 16:14:34 -07001428 EXPECT_EQ(25, curInterval.value.long_value);
1429
1430 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1431 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1432 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001433 EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001434}
1435
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001436TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
Chenjie Yua0f02242018-07-06 16:14:34 -07001437 ValueMetric metric;
1438 metric.set_id(metricId);
1439 metric.set_bucket(ONE_MINUTE);
1440 metric.mutable_value_field()->set_field(tagId);
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001441 metric.mutable_value_field()->add_child()->set_field(2);
1442 metric.set_aggregation_type(ValueMetric::MIN);
1443 metric.set_use_diff(true);
Chenjie Yua0f02242018-07-06 16:14:34 -07001444
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001445 UidMap uidMap;
1446 SimpleAtomMatcher atomMatcher;
1447 atomMatcher.set_atom_id(tagId);
1448 sp<EventMatcherWizard> eventMatcherWizard =
1449 new EventMatcherWizard({new SimpleLogMatchingTracker(
1450 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
Chenjie Yua0f02242018-07-06 16:14:34 -07001451 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
Chenjie Yua0f02242018-07-06 16:14:34 -07001452 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1453
Chenjie Yu054ce9c2018-11-12 15:27:29 -08001454 ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
1455 eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
1456 pullerManager);
Chenjie Yua0f02242018-07-06 16:14:34 -07001457
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001458 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
1459 event1->write(1);
1460 event1->write(10);
1461 event1->init();
1462 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
1463 event2->write(1);
1464 event2->write(15);
1465 event2->init();
1466 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
1467 // has one slice
Chenjie Yua0f02242018-07-06 16:14:34 -07001468 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001469 ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001470 EXPECT_EQ(true, curInterval.hasBase);
1471 EXPECT_EQ(10, curInterval.base.long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001472 EXPECT_EQ(false, curInterval.hasValue);
1473
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001474 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
Chenjie Yua0f02242018-07-06 16:14:34 -07001475
1476 // has one slice
1477 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001478 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001479 EXPECT_EQ(true, curInterval.hasValue);
1480 EXPECT_EQ(5, curInterval.value.long_value);
1481
1482 // no change in data.
1483 shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
1484 event3->write(1);
1485 event3->write(15);
1486 event3->init();
1487 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
1488 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001489 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001490 EXPECT_EQ(true, curInterval.hasBase);
1491 EXPECT_EQ(15, curInterval.base.long_value);
1492 EXPECT_EQ(true, curInterval.hasValue);
1493
1494 shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
1495 event4->write(1);
1496 event4->write(15);
1497 event4->init();
1498 valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
1499 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001500 curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
Chenjie Yuc715b9e2018-10-19 07:52:12 -07001501 EXPECT_EQ(true, curInterval.hasBase);
1502 EXPECT_EQ(15, curInterval.base.long_value);
1503 EXPECT_EQ(true, curInterval.hasValue);
Chenjie Yua0f02242018-07-06 16:14:34 -07001504
1505 valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
1506 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1507 EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
Chenjie Yu32717c32018-10-20 23:54:48 -07001508 EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
Chenjie Yua0f02242018-07-06 16:14:34 -07001509}
1510
Chenjie Yuf275f612018-11-30 23:29:06 -08001511/*
Chenjie Yudbe5c502018-11-30 23:15:57 -08001512 * Tests zero default base.
Chenjie Yuf275f612018-11-30 23:29:06 -08001513 */
1514TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
1515 ValueMetric metric;
1516 metric.set_id(metricId);
1517 metric.set_bucket(ONE_MINUTE);
1518 metric.mutable_value_field()->set_field(tagId);
1519 metric.mutable_value_field()->add_child()->set_field(2);
1520 metric.mutable_dimensions_in_what()->set_field(tagId);
1521 metric.mutable_dimensions_in_what()->add_child()->set_field(1);
1522 metric.set_use_zero_default_base(true);
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001523 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yuf275f612018-11-30 23:29:06 -08001524
1525 UidMap uidMap;
1526 SimpleAtomMatcher atomMatcher;
1527 atomMatcher.set_atom_id(tagId);
1528 sp<EventMatcherWizard> eventMatcherWizard =
1529 new EventMatcherWizard({new SimpleLogMatchingTracker(
1530 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
1531 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1532 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1533 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1534 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001535 EXPECT_CALL(*pullerManager, Pull(tagId, _))
1536 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yuf275f612018-11-30 23:29:06 -08001537 data->clear();
1538 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
1539 event->write(1);
1540 event->write(3);
1541 event->init();
1542 data->push_back(event);
1543 return true;
1544 }));
1545
1546 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
1547 logEventMatcherIndex, eventMatcherWizard, tagId,
1548 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
1549
1550 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1551 auto iter = valueProducer.mCurrentSlicedBucket.begin();
1552 auto& interval1 = iter->second[0];
1553 EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1554 EXPECT_EQ(true, interval1.hasBase);
1555 EXPECT_EQ(3, interval1.base.long_value);
1556 EXPECT_EQ(false, interval1.hasValue);
1557 EXPECT_EQ(true, valueProducer.mHasGlobalBase);
1558 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1559 vector<shared_ptr<LogEvent>> allData;
1560
1561 allData.clear();
1562 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1563 event1->write(2);
1564 event1->write(4);
1565 event1->init();
1566 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1567 event2->write(1);
1568 event2->write(11);
1569 event2->init();
1570 allData.push_back(event1);
1571 allData.push_back(event2);
1572
1573 valueProducer.onDataPulled(allData);
1574 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1575 EXPECT_EQ(true, interval1.hasBase);
1576 EXPECT_EQ(11, interval1.base.long_value);
1577 EXPECT_EQ(true, interval1.hasValue);
1578 EXPECT_EQ(8, interval1.value.long_value);
1579
1580 auto it = valueProducer.mCurrentSlicedBucket.begin();
1581 for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
1582 if (it != iter) {
1583 break;
1584 }
1585 }
1586 EXPECT_TRUE(it != iter);
1587 auto& interval2 = it->second[0];
1588 EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1589 EXPECT_EQ(true, interval2.hasBase);
1590 EXPECT_EQ(4, interval2.base.long_value);
1591 EXPECT_EQ(true, interval2.hasValue);
1592 EXPECT_EQ(4, interval2.value.long_value);
1593 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1594}
1595
1596/*
Chenjie Yudbe5c502018-11-30 23:15:57 -08001597 * Tests using zero default base with failed pull.
Chenjie Yuf275f612018-11-30 23:29:06 -08001598 */
1599TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
1600 ValueMetric metric;
1601 metric.set_id(metricId);
1602 metric.set_bucket(ONE_MINUTE);
1603 metric.mutable_value_field()->set_field(tagId);
1604 metric.mutable_value_field()->add_child()->set_field(2);
1605 metric.mutable_dimensions_in_what()->set_field(tagId);
1606 metric.mutable_dimensions_in_what()->add_child()->set_field(1);
1607 metric.set_use_zero_default_base(true);
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001608 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yuf275f612018-11-30 23:29:06 -08001609
1610 UidMap uidMap;
1611 SimpleAtomMatcher atomMatcher;
1612 atomMatcher.set_atom_id(tagId);
1613 sp<EventMatcherWizard> eventMatcherWizard =
1614 new EventMatcherWizard({new SimpleLogMatchingTracker(
1615 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
1616 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1617 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1618 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1619 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001620 EXPECT_CALL(*pullerManager, Pull(tagId, _))
1621 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yuf275f612018-11-30 23:29:06 -08001622 data->clear();
1623 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
1624 event->write(1);
1625 event->write(3);
1626 event->init();
1627 data->push_back(event);
1628 return true;
1629 }));
1630
1631 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
1632 logEventMatcherIndex, eventMatcherWizard, tagId,
1633 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
1634
1635 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1636 auto iter = valueProducer.mCurrentSlicedBucket.begin();
1637 auto& interval1 = iter->second[0];
1638 EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1639 EXPECT_EQ(true, interval1.hasBase);
1640 EXPECT_EQ(3, interval1.base.long_value);
1641 EXPECT_EQ(false, interval1.hasValue);
1642 EXPECT_EQ(true, valueProducer.mHasGlobalBase);
1643 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1644 vector<shared_ptr<LogEvent>> allData;
1645
1646 allData.clear();
1647 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1648 event1->write(2);
1649 event1->write(4);
1650 event1->init();
1651 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1652 event2->write(1);
1653 event2->write(11);
1654 event2->init();
1655 allData.push_back(event1);
1656 allData.push_back(event2);
1657
1658 valueProducer.onDataPulled(allData);
1659 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1660 EXPECT_EQ(true, interval1.hasBase);
1661 EXPECT_EQ(11, interval1.base.long_value);
1662 EXPECT_EQ(true, interval1.hasValue);
1663 EXPECT_EQ(8, interval1.value.long_value);
1664
1665 auto it = valueProducer.mCurrentSlicedBucket.begin();
1666 for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
1667 if (it != iter) {
1668 break;
1669 }
1670 }
1671 EXPECT_TRUE(it != iter);
1672 auto& interval2 = it->second[0];
1673 EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1674 EXPECT_EQ(true, interval2.hasBase);
1675 EXPECT_EQ(4, interval2.base.long_value);
1676 EXPECT_EQ(true, interval2.hasValue);
1677 EXPECT_EQ(4, interval2.value.long_value);
1678 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1679
1680 // next pull somehow did not happen, skip to end of bucket 3
1681 allData.clear();
1682 event1 = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
1683 event1->write(2);
1684 event1->write(5);
1685 event1->init();
1686 allData.push_back(event1);
1687 valueProducer.onDataPulled(allData);
1688
1689 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1690 EXPECT_EQ(true, interval2.hasBase);
1691 EXPECT_EQ(5, interval2.base.long_value);
1692 EXPECT_EQ(false, interval2.hasValue);
1693 EXPECT_EQ(false, interval1.hasBase);
1694 EXPECT_EQ(false, interval1.hasValue);
1695 EXPECT_EQ(true, valueProducer.mHasGlobalBase);
1696 EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
1697
1698 allData.clear();
1699 event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
1700 event1->write(2);
1701 event1->write(13);
1702 event1->init();
1703 allData.push_back(event1);
1704 event2 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
1705 event2->write(1);
1706 event2->write(5);
1707 event2->init();
1708 allData.push_back(event2);
1709 valueProducer.onDataPulled(allData);
1710
1711 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1712 EXPECT_EQ(true, interval2.hasBase);
1713 EXPECT_EQ(13, interval2.base.long_value);
1714 EXPECT_EQ(true, interval2.hasValue);
1715 EXPECT_EQ(8, interval2.value.long_value);
1716 EXPECT_EQ(true, interval1.hasBase);
1717 EXPECT_EQ(5, interval1.base.long_value);
1718 EXPECT_EQ(true, interval1.hasValue);
1719 EXPECT_EQ(5, interval1.value.long_value);
1720 EXPECT_EQ(true, valueProducer.mHasGlobalBase);
1721 EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
1722}
1723
Chenjie Yudbe5c502018-11-30 23:15:57 -08001724/*
1725 * Tests trim unused dimension key if no new data is seen in an entire bucket.
1726 */
1727TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
1728 ValueMetric metric;
1729 metric.set_id(metricId);
1730 metric.set_bucket(ONE_MINUTE);
1731 metric.mutable_value_field()->set_field(tagId);
1732 metric.mutable_value_field()->add_child()->set_field(2);
1733 metric.mutable_dimensions_in_what()->set_field(tagId);
1734 metric.mutable_dimensions_in_what()->add_child()->set_field(1);
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001735 metric.set_max_pull_delay_sec(INT_MAX);
Chenjie Yudbe5c502018-11-30 23:15:57 -08001736
1737 UidMap uidMap;
1738 SimpleAtomMatcher atomMatcher;
1739 atomMatcher.set_atom_id(tagId);
1740 sp<EventMatcherWizard> eventMatcherWizard =
1741 new EventMatcherWizard({new SimpleLogMatchingTracker(
1742 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
1743 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1744 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1745 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1746 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001747 EXPECT_CALL(*pullerManager, Pull(tagId, _))
1748 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
Chenjie Yudbe5c502018-11-30 23:15:57 -08001749 data->clear();
1750 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
1751 event->write(1);
1752 event->write(3);
1753 event->init();
1754 data->push_back(event);
1755 return true;
1756 }));
1757
1758 ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
1759 logEventMatcherIndex, eventMatcherWizard, tagId,
1760 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
1761
1762 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1763 auto iter = valueProducer.mCurrentSlicedBucket.begin();
1764 auto& interval1 = iter->second[0];
1765 EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1766 EXPECT_EQ(true, interval1.hasBase);
1767 EXPECT_EQ(3, interval1.base.long_value);
1768 EXPECT_EQ(false, interval1.hasValue);
1769 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1770 vector<shared_ptr<LogEvent>> allData;
1771
1772 allData.clear();
1773 shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1774 event1->write(2);
1775 event1->write(4);
1776 event1->init();
1777 shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1778 event2->write(1);
1779 event2->write(11);
1780 event2->init();
1781 allData.push_back(event1);
1782 allData.push_back(event2);
1783
1784 valueProducer.onDataPulled(allData);
1785 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1786 EXPECT_EQ(true, interval1.hasBase);
1787 EXPECT_EQ(11, interval1.base.long_value);
1788 EXPECT_EQ(true, interval1.hasValue);
1789 EXPECT_EQ(8, interval1.value.long_value);
1790 EXPECT_TRUE(interval1.seenNewData);
1791
1792 auto it = valueProducer.mCurrentSlicedBucket.begin();
1793 for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
1794 if (it != iter) {
1795 break;
1796 }
1797 }
1798 EXPECT_TRUE(it != iter);
1799 auto& interval2 = it->second[0];
1800 EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
1801 EXPECT_EQ(true, interval2.hasBase);
1802 EXPECT_EQ(4, interval2.base.long_value);
1803 EXPECT_EQ(false, interval2.hasValue);
1804 EXPECT_TRUE(interval2.seenNewData);
1805 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1806
1807 // next pull somehow did not happen, skip to end of bucket 3
1808 allData.clear();
1809 event1 = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
1810 event1->write(2);
1811 event1->write(5);
1812 event1->init();
1813 allData.push_back(event1);
1814 valueProducer.onDataPulled(allData);
1815
1816 EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
1817
1818 EXPECT_EQ(false, interval1.hasBase);
1819 EXPECT_EQ(false, interval1.hasValue);
1820 EXPECT_EQ(8, interval1.value.long_value);
1821 // on probation now
1822 EXPECT_FALSE(interval1.seenNewData);
1823
1824 EXPECT_EQ(true, interval2.hasBase);
1825 EXPECT_EQ(5, interval2.base.long_value);
1826 EXPECT_EQ(false, interval2.hasValue);
1827 // back to good status
1828 EXPECT_TRUE(interval2.seenNewData);
1829 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1830
1831 allData.clear();
1832 event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
1833 event1->write(2);
1834 event1->write(13);
1835 event1->init();
1836 allData.push_back(event1);
1837 valueProducer.onDataPulled(allData);
1838
1839 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1840 EXPECT_EQ(true, interval2.hasBase);
1841 EXPECT_EQ(13, interval2.base.long_value);
1842 EXPECT_EQ(true, interval2.hasValue);
1843 EXPECT_EQ(8, interval2.value.long_value);
1844 EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
1845}
1846
Chenjie Yu0bd73db2018-12-16 07:37:04 -08001847TEST(ValueMetricProducerTest, TestResetBaseOnPullFail) {
1848 ValueMetric metric;
1849 metric.set_id(metricId);
1850 metric.set_bucket(ONE_MINUTE);
1851 metric.mutable_value_field()->set_field(tagId);
1852 metric.mutable_value_field()->add_child()->set_field(2);
1853 metric.set_condition(StringToId("SCREEN_ON"));
1854 metric.set_max_pull_delay_sec(INT_MAX);
1855
1856 UidMap uidMap;
1857 SimpleAtomMatcher atomMatcher;
1858 atomMatcher.set_atom_id(tagId);
1859 sp<EventMatcherWizard> eventMatcherWizard =
1860 new EventMatcherWizard({new SimpleLogMatchingTracker(
1861 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
1862 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1863 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1864 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1865 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1866
1867 EXPECT_CALL(*pullerManager, Pull(tagId, _))
1868 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
1869 data->clear();
1870 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
1871 event->write(tagId);
1872 event->write(100);
1873 event->init();
1874 data->push_back(event);
1875 return true;
1876 }))
1877 .WillOnce(Return(false));
1878
1879 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1880 eventMatcherWizard, tagId, bucketStartTimeNs,
1881 bucketStartTimeNs, pullerManager);
1882
1883 valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
1884
1885 // has one slice
1886 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1887 ValueMetricProducer::Interval& curInterval =
1888 valueProducer.mCurrentSlicedBucket.begin()->second[0];
1889 EXPECT_EQ(true, curInterval.hasBase);
1890 EXPECT_EQ(100, curInterval.base.long_value);
1891 EXPECT_EQ(false, curInterval.hasValue);
1892 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1893
1894 valueProducer.onConditionChanged(false, bucketStartTimeNs + 20);
1895
1896 // has one slice
1897 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1898 EXPECT_EQ(false, curInterval.hasValue);
1899 EXPECT_EQ(false, curInterval.hasBase);
1900 EXPECT_EQ(false, valueProducer.mHasGlobalBase);
1901}
1902
1903TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
1904 ValueMetric metric;
1905 metric.set_id(metricId);
1906 metric.set_bucket(ONE_MINUTE);
1907 metric.mutable_value_field()->set_field(tagId);
1908 metric.mutable_value_field()->add_child()->set_field(2);
1909 metric.set_condition(StringToId("SCREEN_ON"));
1910 metric.set_max_pull_delay_sec(0);
1911
1912 UidMap uidMap;
1913 SimpleAtomMatcher atomMatcher;
1914 atomMatcher.set_atom_id(tagId);
1915 sp<EventMatcherWizard> eventMatcherWizard =
1916 new EventMatcherWizard({new SimpleLogMatchingTracker(
1917 atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
1918 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1919 sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
1920 EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
1921 EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
1922
1923 EXPECT_CALL(*pullerManager, Pull(tagId, _))
1924 .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
1925 data->clear();
1926 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1927 event->write(tagId);
1928 event->write(120);
1929 event->init();
1930 data->push_back(event);
1931 return true;
1932 }));
1933
1934 ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
1935 eventMatcherWizard, tagId, bucketStartTimeNs,
1936 bucketStartTimeNs, pullerManager);
1937
1938 valueProducer.mCondition = true;
1939 valueProducer.mHasGlobalBase = true;
1940
1941 vector<shared_ptr<LogEvent>> allData;
1942 allData.clear();
1943 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
1944 event->write(1);
1945 event->write(110);
1946 event->init();
1947 allData.push_back(event);
1948 valueProducer.onDataPulled(allData);
1949
1950 // has one slice
1951 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1952 ValueMetricProducer::Interval& curInterval =
1953 valueProducer.mCurrentSlicedBucket.begin()->second[0];
1954 EXPECT_EQ(true, curInterval.hasBase);
1955 EXPECT_EQ(110, curInterval.base.long_value);
1956 EXPECT_EQ(false, curInterval.hasValue);
1957 EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
1958 EXPECT_EQ(true, valueProducer.mHasGlobalBase);
1959
1960 valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
1961
1962 // has one slice
1963 EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
1964 EXPECT_EQ(false, curInterval.hasValue);
1965 EXPECT_EQ(false, curInterval.hasBase);
1966 EXPECT_EQ(false, valueProducer.mHasGlobalBase);
1967}
1968
Chenjie Yu6736c892017-11-09 10:50:09 -08001969} // namespace statsd
1970} // namespace os
1971} // namespace android
1972#else
1973GTEST_LOG_(INFO) << "This test does nothing.\n";
1974#endif