diff options
| author | 2018-05-16 12:23:07 -0700 | |
|---|---|---|
| committer | 2018-05-16 14:50:11 -0700 | |
| commit | 021e25307d815452ceee7e189b36c7072b53c1df (patch) | |
| tree | caa3684afb08cc12867aace6e7da051ece9bf988 | |
| parent | 98c2f7f9de9ada08b8d27243a243a17748282813 (diff) | |
ValueMetric pushed events should check condition
+ fix unit test flakiness
Bug: 79873404
Change-Id: I15b52a79b18c05603640781e4450e7b62fac24ba
Fix: 79873404
Test: unit test
| -rw-r--r-- | cmds/statsd/src/StatsLogProcessor.cpp | 1 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/ValueMetricProducer.cpp | 8 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/ValueMetricProducer.h | 3 | ||||
| -rw-r--r-- | cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp | 1 | ||||
| -rw-r--r-- | cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp | 213 |
6 files changed, 224 insertions, 4 deletions
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 02003c0ee665..766c2d1db5a3 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -83,6 +83,7 @@ StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap, mTimeBaseNs(timeBaseNs), mLargestTimestampSeen(0), mLastTimestampSeen(0) { + mStatsPullerManager.ForceClearPullerCache(); } StatsLogProcessor::~StatsLogProcessor() { diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index 136fd14a8ba3..41e55cb27f5e 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -414,9 +414,11 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked( interval.tainted += 1; } } - } else { // for pushed events - interval.sum += value; - interval.hasValue = true; + } else { // for pushed events, only accumulate when condition is true + if (mCondition == true || mConditionTrackerIndex < 0) { + interval.sum += value; + interval.hasValue = true; + } } long wholeBucketVal = interval.sum; diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 66afa15745e8..cb6b051cd484 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -169,11 +169,14 @@ private: const bool mUseAbsoluteValueOnReset; FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents); + FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset); + FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset); FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition); FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade); FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade); FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse); FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition); + FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition); FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection); FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition); FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition); diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index 13b3cb1e4b3e..67acd6154176 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -84,6 +84,7 @@ StatsdConfig MakeValueMetricConfig(int64_t minTime) { CreateDimensions(android::util::TEMPERATURE, {2 /* sensor name field */}); valueMetric->set_bucket(FIVE_MINUTES); valueMetric->set_min_bucket_size_nanos(minTime); + valueMetric->set_use_absolute_value_on_reset(true); return config; } diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp index 6923e7b5266d..dd28d3611b4f 100644 --- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp @@ -48,7 +48,7 @@ StatsdConfig CreateStatsdConfig() { *valueMetric->mutable_dimensions_in_what() = CreateDimensions(android::util::TEMPERATURE, {2/* sensor name field */ }); valueMetric->set_bucket(FIVE_MINUTES); - + valueMetric->set_use_absolute_value_on_reset(true); return config; } diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 087a612d19ce..e3a8a553acc9 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -129,6 +129,153 @@ TEST(ValueMetricProducerTest, TestNonDimensionalEvents) { } /* + * Tests pulled atoms with no conditions and take absolute value after reset + */ +TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + metric.set_use_absolute_value_on_reset(true); + + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + shared_ptr<MockStatsPullerManager> pullerManager = + make_shared<StrictMock<MockStatsPullerManager>>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, + tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager); + valueProducer.setBucketSize(60 * NS_PER_SEC); + + vector<shared_ptr<LogEvent>> allData; + 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); + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + valueProducer.setBucketSize(60 * NS_PER_SEC); + + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(11, curInterval.start); + EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); + + allData.clear(); + event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1); + event->write(tagId); + event->write(10); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData); + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); + EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValue); + + allData.clear(); + event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1); + event->write(tagId); + event->write(36); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size()); + EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValue); +} + +/* + * Tests pulled atoms with no conditions and take zero value after reset + */ +TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + shared_ptr<MockStatsPullerManager> pullerManager = + make_shared<StrictMock<MockStatsPullerManager>>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, + tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager); + valueProducer.setBucketSize(60 * NS_PER_SEC); + + vector<shared_ptr<LogEvent>> allData; + 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); + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + valueProducer.setBucketSize(60 * NS_PER_SEC); + + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(11, curInterval.start); + EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); + + allData.clear(); + event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1); + event->write(tagId); + event->write(10); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData); + // has one slice + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(0UL, valueProducer.mPastBuckets.size()); + + allData.clear(); + event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1); + event->write(tagId); + event->write(36); + event->init(); + allData.push_back(event); + valueProducer.onDataPulled(allData); + EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(true, curInterval.startUpdated); + EXPECT_EQ(0, curInterval.tainted); + EXPECT_EQ(0, curInterval.sum); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); + EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValue); +} + +/* * Test pulled event with non sliced condition. */ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { @@ -401,6 +548,72 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().mValue); } +TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { + ValueMetric metric; + metric.set_id(metricId); + metric.set_bucket(ONE_MINUTE); + metric.mutable_value_field()->set_field(tagId); + metric.mutable_value_field()->add_child()->set_field(2); + + sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + shared_ptr<MockStatsPullerManager> pullerManager = + make_shared<StrictMock<MockStatsPullerManager>>(); + + ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + valueProducer.setBucketSize(60 * NS_PER_SEC); + + 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(1UL, valueProducer.mCurrentSlicedBucket.size()); + ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(false, curInterval.hasValue); + + 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()); + curInterval = valueProducer.mCurrentSlicedBucket.begin()->second; + EXPECT_EQ(20, curInterval.sum); + + 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; + EXPECT_EQ(50, curInterval.sum); + + 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; + EXPECT_EQ(50, curInterval.sum); + + valueProducer.flushIfNeededLocked(bucket3StartTimeNs); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); + EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); + EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().mValue); +} + TEST(ValueMetricProducerTest, TestAnomalyDetection) { sp<AlarmMonitor> alarmMonitor; Alert alert; |