summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chenjie Yu <cjyu@google.com> 2018-05-16 12:23:07 -0700
committer Chenjie Yu <cjyu@google.com> 2018-05-16 14:50:11 -0700
commit021e25307d815452ceee7e189b36c7072b53c1df (patch)
treecaa3684afb08cc12867aace6e7da051ece9bf988
parent98c2f7f9de9ada08b8d27243a243a17748282813 (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.cpp1
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp8
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h3
-rw-r--r--cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp1
-rw-r--r--cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp2
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp213
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;