summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp1517
1 files changed, 719 insertions, 798 deletions
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 0868aaa3f7a4..fab8e6828977 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -766,805 +766,726 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
{(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)});
EXPECT_FALSE(valueProducer->mCondition);
}
+TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(30, curInterval.value.long_value);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
+ assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+ valueProducer.mCondition = ConditionState::kFalse;
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has 1 slice
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+
+ valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(20, curInterval.value.long_value);
+
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 1, 30);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(50, curInterval.value.long_value);
+
+ valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
+
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 1, 40);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(50, curInterval.value.long_value);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
+ assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20});
+}
+
+TEST(ValueMetricProducerTest, TestAnomalyDetection) {
+ sp<AlarmMonitor> alarmMonitor;
+ Alert alert;
+ alert.set_id(101);
+ alert.set_metric_id(metricId);
+ alert.set_trigger_if_sum_gt(130);
+ alert.set_num_buckets(2);
+ const int32_t refPeriodSec = 3;
+ alert.set_refractory_period_secs(refPeriodSec);
+
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+ sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 1 * NS_PER_SEC, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 2 + NS_PER_SEC, 20);
+
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event3, tagId,
+ bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, 130);
+
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event4, tagId,
+ bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC, 1);
+
+ LogEvent event5(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event5, tagId,
+ bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, 150);
+
+ LogEvent event6(/*uid=*/0, /*pid=*/0);
+ CreateRepeatedValueLogEvent(&event6, tagId,
+ bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC, 160);
+
+ // Two events in bucket #0.
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+ // Value sum == 30 <= 130.
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
+
+ // One event in bucket #2. No alarm as bucket #0 is trashed out.
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
+ // Value sum == 130 <= 130.
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
+
+ // Three events in bucket #3.
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
+ // Anomaly at event 4 since Value sum == 131 > 130!
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
+ std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
+ // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
+ std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
+ // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
+ EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
+ std::ceil(1.0 * event6.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
+}
+
+// Test value metric no condition, the pull on bucket boundary come in time and too late
+TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+ vector<shared_ptr<LogEvent>> allData;
+ // pull 1
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
+
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ // startUpdated:true sum:0 start:11
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(11, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+ // pull 2 at correct time
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ // tartUpdated:false sum:12
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(23, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
+
+ // pull 3 come late.
+ // The previous bucket gets closed with error. (Has start value 23, no ending)
+ // Another bucket gets closed with error. (No start, but ending with 36)
+ // The new bucket is back to normal.
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket6StartTimeNs + 1, 36));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ // startUpdated:false sum:12
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(36, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
+}
+
+/*
+ * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
+ * was delivered late.
+ */
+TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // condition becomes true
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
+ return true;
+ }))
+ // condition becomes false
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
+ return true;
+ }));
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+ valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(100, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+ // pull on bucket boundary come late, condition change happens before it
+ valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
+ EXPECT_EQ(false, curBaseInfo.hasBase);
+
+ // Now the alarm is delivered.
+ // since the condition turned to off before this pull finish, it has no effect
+ vector<shared_ptr<LogEvent>> allData;
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(false, curBaseInfo.hasBase);
+ EXPECT_EQ(false, curInterval.hasValue);
+}
+
+/*
+* Test pulled event with non sliced condition. The pull on boundary come late, after the
+condition
+* change to false, and then true again. This is due to alarm delivered late.
+*/
+TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // condition becomes true
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
+ return true;
+ }))
+ // condition becomes false
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
+ return true;
+ }))
+ // condition becomes true again
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
+ return true;
+ }));
+
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+ valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ // startUpdated:false sum:0 start:100
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(100, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+ // pull on bucket boundary come late, condition change happens before it
+ valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(false, curBaseInfo.hasBase);
+ EXPECT_EQ(false, curInterval.hasValue);
+
+ // condition changed to true again, before the pull alarm is delivered
+ valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(130, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+
+ // Now the alarm is delivered, but it is considered late, the data will be used
+ // for the new bucket since it was just pulled.
+ vector<shared_ptr<LogEvent>> allData;
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 50, 140));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
+
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(140, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(10, curInterval.value.long_value);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
+
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 160));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+ assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20, 30},
+ {bucketSizeNs - 8, bucketSizeNs - 24});
+}
+
+TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_aggregation_type(ValueMetric::MIN);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
+ assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_aggregation_type(ValueMetric::MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(20, curInterval.value.long_value);
+
+ valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
+ /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); */
+ /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); */
+ /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */
+}
+
+TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_aggregation_type(ValueMetric::AVG);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 15);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(1, curInterval.sampleSize);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(25, curInterval.value.long_value);
+ EXPECT_EQ(2, curInterval.sampleSize);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+
+ EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
+ 12.5) < epsilon);
+}
+
+TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_aggregation_type(ValueMetric::SUM);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 15);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(25, curInterval.value.long_value);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
+ assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_aggregation_type(ValueMetric::MIN);
+ metric.set_use_diff(true);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(10, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(5, curInterval.value.long_value);
+
+ // no change in data.
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(15, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ CreateTwoValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(15, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.mutable_value_field()->add_child()->set_field(3);
+ metric.set_aggregation_type(ValueMetric::MIN);
+ metric.set_use_diff(true);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ LogEvent event1(/*uid=*/0, /*pid=*/0);
+ CreateThreeValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10, 20);
+
+ LogEvent event2(/*uid=*/0, /*pid=*/0);
+ CreateThreeValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15, 22);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(10, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(20, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(5, curInterval.value.long_value);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(2, curInterval.value.long_value);
+
+ // no change in first value field
+ LogEvent event3(/*uid=*/0, /*pid=*/0);
+ CreateThreeValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15, 25);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(15, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(25, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ LogEvent event4(/*uid=*/0, /*pid=*/0);
+ CreateThreeValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15, 29);
+
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(15, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
+ curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(29, curBaseInfo.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
+
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
+
+ EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
+ EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
+ EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
+ EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
+
+ EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
+ EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
+ EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
+}
-// TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(20);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(10,
-// curInterval.value.long_value); EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(30, curInterval.value.long_value);
-//
-// valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs});
-//}
-//
-// TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-// valueProducer.mCondition = ConditionState::kFalse;
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has 1 slice
-// EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-//
-// valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(20);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(20, curInterval.value.long_value);
-//
-// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
-// event3->write(1);
-// event3->write(30);
-// event3->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(50, curInterval.value.long_value);
-//
-// valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
-// shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 40);
-// event4->write(1);
-// event4->write(40);
-// event4->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(50, curInterval.value.long_value);
-//
-// valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20});
-//}
-//
-// TEST(ValueMetricProducerTest, TestAnomalyDetection) {
-// sp<AlarmMonitor> alarmMonitor;
-// Alert alert;
-// alert.set_id(101);
-// alert.set_metric_id(metricId);
-// alert.set_trigger_if_sum_gt(130);
-// alert.set_num_buckets(2);
-// const int32_t refPeriodSec = 3;
-// alert.set_refractory_period_secs(refPeriodSec);
-//
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-// logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
-// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-//
-// sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
-//
-//
-// shared_ptr<LogEvent> event1
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1 * NS_PER_SEC);
-// event1->write(161);
-// event1->write(10); // value of interest
-// event1->init();
-// shared_ptr<LogEvent> event2
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 + NS_PER_SEC);
-// event2->write(162);
-// event2->write(20); // value of interest
-// event2->init();
-// shared_ptr<LogEvent> event3
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC);
-// event3->write(163);
-// event3->write(130); // value of interest
-// event3->init();
-// shared_ptr<LogEvent> event4
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC);
-// event4->write(35);
-// event4->write(1); // value of interest
-// event4->init();
-// shared_ptr<LogEvent> event5
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC);
-// event5->write(45);
-// event5->write(150); // value of interest
-// event5->init();
-// shared_ptr<LogEvent> event6
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 *
-// NS_PER_SEC);
-// event6->write(25);
-// event6->write(160); // value of interest
-// event6->init();
-//
-// // Two events in bucket #0.
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-// // Value sum == 30 <= 130.
-// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-//
-// // One event in bucket #2. No alarm as bucket #0 is trashed out.
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
-// // Value sum == 130 <= 130.
-// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-//
-// // Three events in bucket #3.
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
-// // Anomaly at event 4 since Value sum == 131 > 130!
-// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-// std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event5);
-// // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
-// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-// std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event6);
-// // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
-// EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-// std::ceil(1.0 * event6->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-//}
-//
-//// Test value metric no condition, the pull on bucket boundary come in time and too late
-// TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
-// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-// vector<shared_ptr<LogEvent>> allData;
-// // pull 1
-// allData.clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-// event->write(tagId);
-// event->write(11);
-// event->init();
-// allData.push_back(event);
-//
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo =
-// valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// // startUpdated:true sum:0 start:11
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(11, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-// // pull 2 at correct time
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-// event->write(tagId);
-// event->write(23);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// // tartUpdated:false sum:12
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(23, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
-//
-// // pull 3 come late.
-// // The previous bucket gets closed with error. (Has start value 23, no ending)
-// // Another bucket gets closed with error. (No start, but ending with 36)
-// // The new bucket is back to normal.
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket6StartTimeNs + 1);
-// event->write(tagId);
-// event->write(36);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// // startUpdated:false sum:12
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(36, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
-//}
-//
-///*
-// * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
-// * was delivered late.
-// */
-// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, Pull(tagId, _))
-// // condition becomes true
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
-// event->write(tagId);
-// event->write(100);
-// event->init();
-// data->push_back(event);
-// return true;
-// }))
-// // condition becomes false
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-// event->write(tagId);
-// event->write(120);
-// event->init();
-// data->push_back(event);
-// return true;
-// }));
-// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
-// metric);
-//
-// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo =
-// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(100, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-// // pull on bucket boundary come late, condition change happens before it
-// valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
-// EXPECT_EQ(false, curBaseInfo.hasBase);
-//
-// // Now the alarm is delivered.
-// // since the condition turned to off before this pull finish, it has no effect
-// vector<shared_ptr<LogEvent>> allData;
-// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 110));
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
-// EXPECT_EQ(false, curInterval.hasValue);
-//}
-//
-///*
-// * Test pulled event with non sliced condition. The pull on boundary come late, after the
-// condition
-// * change to false, and then true again. This is due to alarm delivered late.
-// */
-// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, Pull(tagId, _))
-// // condition becomes true
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
-// event->write(tagId);
-// event->write(100);
-// event->init();
-// data->push_back(event);
-// return true;
-// }))
-// // condition becomes false
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-// event->write(tagId);
-// event->write(120);
-// event->init();
-// data->push_back(event);
-// return true;
-// }))
-// // condition becomes true again
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
-// 25); event->write(tagId); event->write(130); event->init();
-// data->push_back(event);
-// return true;
-// }));
-//
-// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
-// metric);
-//
-// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo =
-// valueProducer->mCurrentBaseInfo.begin()->second[0];
-// // startUpdated:false sum:0 start:100
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(100, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-// // pull on bucket boundary come late, condition change happens before it
-// valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
-// EXPECT_EQ(false, curInterval.hasValue);
-//
-// // condition changed to true again, before the pull alarm is delivered
-// valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(130, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-//
-// // Now the alarm is delivered, but it is considered late, the data will be used
-// // for the new bucket since it was just pulled.
-// vector<shared_ptr<LogEvent>> allData;
-// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 50, 140));
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
-//
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(140, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-// EXPECT_EQ(10, curInterval.value.long_value);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
-//
-// allData.clear();
-// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs, 160));
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20, 30},
-// {bucketSizeNs - 8, bucketSizeNs - 24});
-//}
-//
-// TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_aggregation_type(ValueMetric::MIN);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(20);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-//
-// valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs});
-//}
-//
-// TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_aggregation_type(ValueMetric::MAX);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(20);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(20, curInterval.value.long_value);
-//
-// valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-// /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); */
-// /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); */
-// /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */
-//}
-//
-// TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_aggregation_type(ValueMetric::AVG);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(15);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval;
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-// EXPECT_EQ(1, curInterval.sampleSize);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(25, curInterval.value.long_value);
-// EXPECT_EQ(2, curInterval.sampleSize);
-//
-// valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-//
-// EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value
-// -
-// 12.5) < epsilon);
-//}
-//
-// TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_aggregation_type(ValueMetric::SUM);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-// event2->write(1);
-// event2->write(15);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(25, curInterval.value.long_value);
-//
-// valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs});
-//}
-//
-// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_aggregation_type(ValueMetric::MIN);
-// metric.set_use_diff(true);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
-// event2->write(1);
-// event2->write(15);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(10, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// EXPECT_EQ(true, curInterval.hasValue);
-// EXPECT_EQ(5, curInterval.value.long_value);
-//
-// // no change in data.
-// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-// event3->write(1);
-// event3->write(15);
-// event3->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(15, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
-// event4->write(1);
-// event4->write(15);
-// event4->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(15, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs});
-//}
-//
-// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.mutable_value_field()->add_child()->set_field(3);
-// metric.set_aggregation_type(ValueMetric::MIN);
-// metric.set_use_diff(true);
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-//
-// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-// event1->write(1);
-// event1->write(10);
-// event1->write(20);
-// event1->init();
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
-// event2->write(1);
-// event2->write(15);
-// event2->write(22);
-// event2->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(10, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(20, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-//
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curInterval.hasValue);
-// EXPECT_EQ(5, curInterval.value.long_value);
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
-// EXPECT_EQ(true, curInterval.hasValue);
-// EXPECT_EQ(2, curInterval.value.long_value);
-//
-// // no change in first value field
-// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-// event3->write(1);
-// event3->write(15);
-// event3->write(25);
-// event3->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(15, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(25, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
-// event4->write(1);
-// event4->write(15);
-// event4->write(29);
-// event4->init();
-// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
-// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(15, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-// curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[1];
-// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[1];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(29, curBaseInfo.base.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
-//
-// valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-//
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-// EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
-// EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
-// EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
-//
-// EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
-// EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
-// EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
-// EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
-//
-// EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
-// EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
-// EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
-//}
-//
///*
// * Tests zero default base.
// */