Fix ConditionUnknown after valid buckets

Because non-zero enums are evaluated to true, it is possible for pulls
to occur on bucket split even if the condition is unknown. Explicitly
check that the condition is true instead.

Bug: 155489707
Test: atest statsd_test
Change-Id: I0bc3de6e885c2200885caf01d07c793b83eca17a
This commit is contained in:
Jeffrey Huang
2020-06-04 12:31:47 -07:00
parent a2d82aeb16
commit 3be5671c03
2 changed files with 42 additions and 2 deletions

View File

@@ -75,7 +75,7 @@ public:
if (!mSplitBucketForAppUpgrade) {
return;
}
if (mIsPulled && mCondition) {
if (mIsPulled && mCondition == ConditionState::kTrue) {
pullAndMatchEventsLocked(eventTimeNs);
}
flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
@@ -84,7 +84,7 @@ public:
// ValueMetric needs special logic if it's a pulled atom.
void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
std::lock_guard<std::mutex> lock(mMutex);
if (mIsPulled && mCondition) {
if (mIsPulled && mCondition == ConditionState::kTrue) {
pullAndMatchEventsLocked(eventTimeNs);
}
flushCurrentBucketLocked(eventTimeNs, eventTimeNs);

View File

@@ -4722,6 +4722,46 @@ TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
EXPECT_EQ(5, report.value_metrics().data(4).bucket_info(1).values(0).value_long());
}
/*
* Test bucket splits when condition is unknown.
*/
TEST(ValueMetricProducerTest, TestForcedBucketSplitWhenConditionUnknownSkipsBucket) {
ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
sp<ValueMetricProducer> valueProducer =
ValueMetricProducerTestHelper::createValueProducerWithCondition(
pullerManager, metric,
ConditionState::kUnknown);
// App update event.
int64_t appUpdateTimeNs = bucketStartTimeNs + 1000;
valueProducer->notifyAppUpgrade(appUpdateTimeNs);
// Check dump report.
ProtoOutputStream output;
std::set<string> strSet;
int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
StatsLogReport report = outputStreamToProto(&output);
EXPECT_TRUE(report.has_value_metrics());
ASSERT_EQ(0, report.value_metrics().data_size());
ASSERT_EQ(1, report.value_metrics().skipped_size());
EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
report.value_metrics().skipped(0).start_bucket_elapsed_millis());
EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
report.value_metrics().skipped(0).end_bucket_elapsed_millis());
ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
}
} // namespace statsd
} // namespace os
} // namespace android