diff options
| -rw-r--r-- | cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp | 1890 |
1 files changed, 892 insertions, 998 deletions
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 7b0467c5d5a0..27addc703ecd 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -2559,1004 +2559,898 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { // EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size()); // EXPECT_EQ(1UL, valueProducer->mPastBuckets.size()); //} -// -// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // First onConditionChanged -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(3); -// event->init(); -// data->push_back(event); -// return true; -// })) -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); -// 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(false, curInterval.hasValue); -// EXPECT_EQ(true, valueProducer->mHasGlobalBase); -// -// // Empty pull. -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); -// 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); -// EXPECT_EQ(false, valueProducer->mHasGlobalBase); -//} -// -// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // First onConditionChanged -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(1); -// event->init(); -// data->push_back(event); -// return true; -// })) -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(2); -// event->init(); -// data->push_back(event); -// return true; -// })) -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(5); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 11); -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 12); -// 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(true, curInterval.hasValue); -// EXPECT_EQ(true, valueProducer->mHasGlobalBase); -// -// // End of bucket -// vector<shared_ptr<LogEvent>> allData; -// allData.clear(); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); -// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; -// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; -// // Data is empty, base should be reset. -// EXPECT_EQ(false, curBaseInfo.hasBase); -// EXPECT_EQ(5, curBaseInfo.base.long_value); -// EXPECT_EQ(false, curInterval.hasValue); -// EXPECT_EQ(true, valueProducer->mHasGlobalBase); -// -// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size()); -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1}); -//} -// -// TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// metric.mutable_dimensions_in_what()->set_field(tagId); -// metric.mutable_dimensions_in_what()->add_child()->set_field(1); -// metric.set_condition(StringToId("SCREEN_ON")); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // First onConditionChanged -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(1); -// event->write(1); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); -// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); -// -// // End of bucket -// vector<shared_ptr<LogEvent>> allData; -// allData.clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); -// event->write(2); -// event->write(2); -// event->init(); -// allData.push_back(event); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // Key 1 should be reset since in not present in the most pull. -// EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size()); -// auto iterator = valueProducer->mCurrentSlicedBucket.begin(); -// auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin(); -// EXPECT_EQ(true, baseInfoIter->second[0].hasBase); -// EXPECT_EQ(2, baseInfoIter->second[0].base.long_value); -// EXPECT_EQ(false, iterator->second[0].hasValue); -// iterator++; -// baseInfoIter++; -// EXPECT_EQ(false, baseInfoIter->second[0].hasBase); -// EXPECT_EQ(1, baseInfoIter->second[0].base.long_value); -// EXPECT_EQ(false, iterator->second[0].hasValue); -// -// EXPECT_EQ(true, valueProducer->mHasGlobalBase); -//} -// -// TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initialization. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1)); -// return true; -// })) -// // notifyAppUpgrade. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent( -// bucketStartTimeNs + bucketSizeNs / 2, 10)); -// return true; -// })); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); -// ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); -// -// valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1); -// ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size()); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 1, 4)); -// valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1); -// ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); -//} -// -// TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Second onConditionChanged. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back( -// ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 10, 5)); -// return true; -// })) -// // Third onConditionChanged. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back( -// ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 10, 7)); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->mCondition = ConditionState::kUnknown; -// -// valueProducer->onConditionChanged(false, bucketStartTimeNs); -// ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size()); -// -// // End of first bucket -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 4)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1); -// ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size()); -// -// valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); -// ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); -// auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; -// auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; -// EXPECT_EQ(true, curBaseInfo.hasBase); -// EXPECT_EQ(5, curBaseInfo.base.long_value); -// EXPECT_EQ(false, curInterval.hasValue); -// -// valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10); -// -// // Bucket should have been completed. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10}); -//} -// -// TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// metric.set_use_diff(false); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30); -// -// allData.clear(); -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // Bucket should have been completed. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs}); -//} -// -// TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initialization. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1)); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30); -// -// allData.clear(); -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // Bucket should have been completed. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs}); -//} -// -// TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initialization. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1)); -// return true; -// })) -// // notifyAppUpgrade. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back( -// ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 2, 10)); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); -// -// valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1); -// -// // Bucket should have been completed. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs}); -//} -// -// TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // First on condition changed. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1)); -// return true; -// })) -// // Second on condition changed. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 3)); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); -// -// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); -// auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; -// auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; -// EXPECT_EQ(true, curInterval.hasValue); -// EXPECT_EQ(2, curInterval.value.long_value); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 10)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1); -// -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}); -//} -// -//// TODO: b/145705635 fix or delete this test -// TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // First condition change. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1)); -// return true; -// })) -// // 2nd condition change. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, -// 1)); return true; -// })) -// // 3rd condition change. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, -// 1)); return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 3, 10)); -// valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3); -// -// allData.clear(); -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20)); -// valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs); -// -// valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8); -// valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); -// -// allData.clear(); -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs, 30)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // There was not global base available so all buckets are invalid. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); -//} -// -// TEST(ValueMetricProducerTest, TestPullNeededFastDump) { -// 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>(); -// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); -// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); -// -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initial pull. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(1); -// event->write(1); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, -// eventMatcherWizard, tagId, bucketStartTimeNs, -// bucketStartTimeNs, pullerManager); -// -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true, -// FAST, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// // Bucket is invalid since we did not pull when dump report was called. -// EXPECT_EQ(0, report.value_metrics().data_size()); -//} -// -// TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) { -// 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>(); -// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); -// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); -// -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initial pull. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(1); -// event->write(1); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, -// eventMatcherWizard, tagId, bucketStartTimeNs, -// bucketStartTimeNs, pullerManager); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1); -// event->write(tagId); -// event->write(2); -// event->write(2); -// event->init(); -// allData.push_back(event); -// valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST, -// &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// // Previous bucket is part of the report. -// EXPECT_EQ(1, report.value_metrics().data_size()); -// EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num()); -//} -// -// TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) { -// 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>(); -// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); -// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); -// -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Initial pull. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs); -// event->write(tagId); -// event->write(1); -// event->write(1); -// event->init(); -// data->push_back(event); -// return true; -// })) -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10); -// event->write(tagId); -// event->write(3); -// event->write(3); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, -// eventMatcherWizard, tagId, bucketStartTimeNs, -// bucketStartTimeNs, pullerManager); -// -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true, -// NO_TIME_CONSTRAINTS, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_EQ(1, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size()); -// EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long()); -//} -// -// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); -// metric.set_use_diff(false); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); -// -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 10)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30); -// -// // Bucket should have been completed. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs}); -//} -// -// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// metric.set_use_diff(false); -// -// 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( -// ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10)); -// return true; -// })) -// // condition becomes false -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// data->push_back( -// ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 50, 20)); -// return true; -// })); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->mCondition = ConditionState::kFalse; -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 50); -// // 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(false, curBaseInfo.hasBase); -// EXPECT_EQ(true, curInterval.hasValue); -// EXPECT_EQ(20, curInterval.value.long_value); -// -// // Now the alarm is delivered. Condition is off though. -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 110)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8}); -// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; -// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; -// EXPECT_EQ(false, curBaseInfo.hasBase); -// EXPECT_EQ(false, curInterval.hasValue); -//} -// -// TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// metric.set_use_diff(false); -// -// 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( -// ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10)); -// return true; -// })); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->mCondition = ConditionState::kFalse; -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); -// -// // Now the alarm is delivered. Condition is off though. -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8}); -// ValueMetricProducer::Interval curInterval = -// valueProducer->mCurrentSlicedBucket.begin()->second[0]; -// ValueMetricProducer::BaseInfo curBaseInfo = -// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase); -// EXPECT_EQ(false, curInterval.hasValue); -//} -// -// TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// metric.set_use_diff(false); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->mCondition = ConditionState::kFalse; -// -// // Now the alarm is delivered. Condition is off though. -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // Condition was always false. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); -//} -// -// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// metric.set_use_diff(false); -// -// 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( -// ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10)); -// return true; -// })) -// .WillOnce(Return(false)); -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// valueProducer->mCondition = ConditionState::kFalse; -// -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); -// valueProducer->onConditionChanged(false, bucketStartTimeNs + 50); -// -// // Now the alarm is delivered. Condition is off though. -// vector<shared_ptr<LogEvent>> allData; -// allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30)); -// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); -// -// // No buckets, we had a failure. -// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); -//} -// -///* -// * Test that DUMP_REPORT_REQUESTED dump reason is logged. -// * -// * For the bucket to be marked invalid during a dump report requested, -// * three things must be true: -// * - we want to include the current partial bucket -// * - we need a pull (metric is pulled and condition is true) -// * - the dump latency must be FAST -// */ -// -// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Condition change to true. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20); -// event->write("field1"); -// event->write(10); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// // Condition change event. -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 20); -// -// // Check dump report. -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true, -// FAST /* dumpLatency */, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_TRUE(report.has_value_metrics()); -// EXPECT_EQ(0, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().skipped_size()); -// -// EXPECT_EQ(NanoToMillis(bucketStartTimeNs), -// report.value_metrics().skipped(0).start_bucket_elapsed_millis()); -// EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), -// report.value_metrics().skipped(0).end_bucket_elapsed_millis()); -// EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); -// -// auto dropEvent = report.value_metrics().skipped(0).drop_event(0); -// EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason()); -// EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis()); -//} -// -///* -// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition -// * change event (i.e. the condition change occurs in the wrong bucket). -// */ -// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Condition change to true. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50); -// event->write("field1"); -// event->write(10); -// event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// // Condition change event. -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); -// -// // Bucket boundary pull. -// vector<shared_ptr<LogEvent>> allData; -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs); -// event->write("field1"); -// event->write(15); -// event->init(); -// allData.push_back(event); -// valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1); -// -// // Late condition change event. -// valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100); -// -// // Check dump report. -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true, -// NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_TRUE(report.has_value_metrics()); -// EXPECT_EQ(1, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().skipped_size()); -// -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), -// report.value_metrics().skipped(0).start_bucket_elapsed_millis()); -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), -// report.value_metrics().skipped(0).end_bucket_elapsed_millis()); -// EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); -// -// auto dropEvent = report.value_metrics().skipped(0).drop_event(0); -// EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason()); -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis()); -//} -// -///* -// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate -// * event (i.e. the accumulate events call occurs in the wrong bucket). -// */ -// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Condition change to true. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50); -// event->write("field1"); -// event->write(10); -// event->init(); -// data->push_back(event); -// return true; -// })) -// // Dump report requested. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + -// 100); event->write("field1"); event->write(15); event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// // Condition change event. -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); -// -// // Bucket boundary pull. -// vector<shared_ptr<LogEvent>> allData; -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs); -// event->write("field1"); -// event->write(15); -// event->init(); -// allData.push_back(event); -// valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1); -// -// allData.clear(); -// event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100); -// event->write("field1"); -// event->write(20); -// event->init(); -// allData.push_back(event); -// -// // Late accumulateEvents event. -// valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100); -// -// // Check dump report. -// ProtoOutputStream output; -// std::set<string> strSet; -// valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true, -// NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_TRUE(report.has_value_metrics()); -// EXPECT_EQ(1, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().skipped_size()); -// -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), -// report.value_metrics().skipped(0).start_bucket_elapsed_millis()); -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), -// report.value_metrics().skipped(0).end_bucket_elapsed_millis()); -// EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); -// -// auto dropEvent = report.value_metrics().skipped(0).drop_event(0); -// EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason()); -// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis()); -//} -// -///* -// * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition -// * when a metric is initialized. -// */ -// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Condition change to true. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50); -// event->write("field1"); -// event->write(10); -// event->init(); -// data->push_back(event); -// return true; -// })) -// // Dump report requested. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + -// 100); event->write("field1"); event->write(15); event->init(); -// data->push_back(event); -// return true; -// })); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager, -// metric); -// -// // Condition change event. -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); -// -// // Check dump report. -// ProtoOutputStream output; -// std::set<string> strSet; -// int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; -// valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, -// NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_TRUE(report.has_value_metrics()); -// EXPECT_EQ(0, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().skipped_size()); -// -// EXPECT_EQ(NanoToMillis(bucketStartTimeNs), -// report.value_metrics().skipped(0).start_bucket_elapsed_millis()); -// EXPECT_EQ(NanoToMillis(dumpReportTimeNs), -// report.value_metrics().skipped(0).end_bucket_elapsed_millis()); -// EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); -// -// auto dropEvent = report.value_metrics().skipped(0).drop_event(0); -// EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason()); -// EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); -//} -// -///* -// * Test that PULL_FAILED dump reason is logged due to a pull failure in -// * #pullAndMatchEventsLocked. -// */ -// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) { -// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); -// -// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); -// EXPECT_CALL(*pullerManager, Pull(tagId, _)) -// // Condition change to true. -// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { -// data->clear(); -// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50); -// event->write("field1"); -// event->write(10); -// event->init(); -// data->push_back(event); -// return true; -// })) -// // Dump report requested, pull fails. -// .WillOnce(Return(false)); -// -// sp<ValueMetricProducer> valueProducer = -// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, -// metric); -// -// // Condition change event. -// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); -// -// // Check dump report. -// ProtoOutputStream output; -// std::set<string> strSet; -// int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; -// valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, -// NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); -// -// StatsLogReport report = outputStreamToProto(&output); -// EXPECT_TRUE(report.has_value_metrics()); -// EXPECT_EQ(0, report.value_metrics().data_size()); -// EXPECT_EQ(1, report.value_metrics().skipped_size()); -// -// EXPECT_EQ(NanoToMillis(bucketStartTimeNs), -// report.value_metrics().skipped(0).start_bucket_elapsed_millis()); -// EXPECT_EQ(NanoToMillis(dumpReportTimeNs), -// report.value_metrics().skipped(0).end_bucket_elapsed_millis()); -// EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); -// -// auto dropEvent = report.value_metrics().skipped(0).drop_event(0); -// EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason()); -// EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); -//} -// + +TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3)); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); + 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(false, curInterval.hasValue); + EXPECT_EQ(true, valueProducer->mHasGlobalBase); + + // Empty pull. + valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); + 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); + EXPECT_EQ(false, valueProducer->mHasGlobalBase); +} + +TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2)); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 11); + valueProducer->onConditionChanged(true, bucketStartTimeNs + 12); + 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(true, curInterval.hasValue); + EXPECT_EQ(true, valueProducer->mHasGlobalBase); + + // End of bucket + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); + curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; + curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; + // Data is empty, base should be reset. + EXPECT_EQ(false, curBaseInfo.hasBase); + EXPECT_EQ(5, curBaseInfo.base.long_value); + EXPECT_EQ(false, curInterval.hasValue); + EXPECT_EQ(true, valueProducer->mHasGlobalBase); + + EXPECT_EQ(1UL, valueProducer->mPastBuckets.size()); + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1}); +} + +TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + metric.mutable_dimensions_in_what()->set_field(tagId); + metric.mutable_dimensions_in_what()->add_child()->set_field(1); + metric.set_condition(StringToId("SCREEN_ON")); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First onConditionChanged + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 10); + EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); + + // End of bucket + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 2)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // Key 1 should be reset since in not present in the most pull. + EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size()); + auto iterator = valueProducer->mCurrentSlicedBucket.begin(); + auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin(); + EXPECT_EQ(true, baseInfoIter->second[0].hasBase); + EXPECT_EQ(2, baseInfoIter->second[0].base.long_value); + EXPECT_EQ(false, iterator->second[0].hasValue); + iterator++; + baseInfoIter++; + EXPECT_EQ(false, baseInfoIter->second[0].hasBase); + EXPECT_EQ(1, baseInfoIter->second[0].base.long_value); + EXPECT_EQ(false, iterator->second[0].hasValue); + + EXPECT_EQ(true, valueProducer->mHasGlobalBase); +} + +TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initialization. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })) + // notifyAppUpgrade. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent( + tagId, bucketStartTimeNs + bucketSizeNs / 2, 10)); + return true; + })); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); + ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); + + valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1); + ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size()); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4)); + valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1); + ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size()); +} + +TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Second onConditionChanged. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5)); + return true; + })) + // Third onConditionChanged. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->mCondition = ConditionState::kUnknown; + + valueProducer->onConditionChanged(false, bucketStartTimeNs); + ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size()); + + // End of first bucket + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 4)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1); + ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size()); + + valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); + ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); + auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; + auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; + EXPECT_EQ(true, curBaseInfo.hasBase); + EXPECT_EQ(5, curBaseInfo.base.long_value); + EXPECT_EQ(false, curInterval.hasValue); + + valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10); + + // Bucket should have been completed. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10}); +} + +TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + metric.set_use_diff(false); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30); + + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // Bucket should have been completed. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs}); +} + +TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initialization. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30); + + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // Bucket should have been completed. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs}); +} + +TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initialization. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })) + // notifyAppUpgrade. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 2, 10)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); + + valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1); + + // Bucket should have been completed. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs}); +} + +TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First on condition changed. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })) + // Second on condition changed. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 10); + + EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size()); + auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; + auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; + EXPECT_EQ(true, curInterval.hasValue); + EXPECT_EQ(2, curInterval.value.long_value); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1); + + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}); +} + +// TODO: b/145705635 fix or delete this test +TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // First condition change. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1)); + return true; + })) + // 2nd condition change. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1)); + return true; + })) + // 3rd condition change. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 3, 10)); + valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3); + + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20)); + valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs); + + valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8); + valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10); + + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 30)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // There was not global base available so all buckets are invalid. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); +} + +TEST(ValueMetricProducerTest, TestPullNeededFastDump) { + 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>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initial pull. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1)); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + ProtoOutputStream output; + std::set<string> strSet; + valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true, + FAST, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + // Bucket is invalid since we did not pull when dump report was called. + EXPECT_EQ(0, report.value_metrics().data_size()); +} + +TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) { + 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>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initial pull. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1)); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + vector<shared_ptr<LogEvent>> allData; + allData.clear(); + allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, tagId, 2, 2)); + valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + ProtoOutputStream output; + std::set<string> strSet; + valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST, + &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + // Previous bucket is part of the report. + EXPECT_EQ(1, report.value_metrics().data_size()); + EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num()); +} + +TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) { + 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>(); + EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); + EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); + + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Initial pull. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1)); + return true; + })) + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back( + CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3)); + return true; + })); + + ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex, + eventMatcherWizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); + + ProtoOutputStream output; + std::set<string> strSet; + valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_EQ(1, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size()); + EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long()); +} + +TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); + metric.set_use_diff(false); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric); + + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 10)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30); + + // Bucket should have been completed. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs}); +} + +TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + metric.set_use_diff(false); + + 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 + 30, 10)); + return true; + })) + // condition becomes false + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20)); + return true; + })); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->mCondition = ConditionState::kFalse; + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 50); + // 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(false, curBaseInfo.hasBase); + EXPECT_EQ(true, curInterval.hasValue); + EXPECT_EQ(20, curInterval.value.long_value); + + // Now the alarm is delivered. Condition is off though. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8}); + curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0]; + curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; + EXPECT_EQ(false, curBaseInfo.hasBase); + EXPECT_EQ(false, curInterval.hasValue); +} + +TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + metric.set_use_diff(false); + + 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 + 30, 10)); + return true; + })); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->mCondition = ConditionState::kFalse; + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); + + // Now the alarm is delivered. Condition is off though. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8}); + ValueMetricProducer::Interval curInterval = + valueProducer->mCurrentSlicedBucket.begin()->second[0]; + ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0]; + EXPECT_EQ(false, curBaseInfo.hasBase); + EXPECT_EQ(false, curInterval.hasValue); +} + +TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + metric.set_use_diff(false); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->mCondition = ConditionState::kFalse; + + // Now the alarm is delivered. Condition is off though. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // Condition was always false. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); +} + +TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + metric.set_use_diff(false); + + 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 + 30, 10)); + return true; + })) + .WillOnce(Return(false)); + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + valueProducer->mCondition = ConditionState::kFalse; + + valueProducer->onConditionChanged(true, bucketStartTimeNs + 8); + valueProducer->onConditionChanged(false, bucketStartTimeNs + 50); + + // Now the alarm is delivered. Condition is off though. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30)); + valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); + + // No buckets, we had a failure. + assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}); +} + +/* + * Test that DUMP_REPORT_REQUESTED dump reason is logged. + * + * For the bucket to be marked invalid during a dump report requested, + * three things must be true: + * - we want to include the current partial bucket + * - we need a pull (metric is pulled and condition is true) + * - the dump latency must be FAST + */ + +TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Condition change to true. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + // Condition change event. + valueProducer->onConditionChanged(true, bucketStartTimeNs + 20); + + // Check dump report. + ProtoOutputStream output; + std::set<string> strSet; + valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true, + FAST /* dumpLatency */, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_TRUE(report.has_value_metrics()); + EXPECT_EQ(0, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().skipped_size()); + + EXPECT_EQ(NanoToMillis(bucketStartTimeNs), + report.value_metrics().skipped(0).start_bucket_elapsed_millis()); + EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), + report.value_metrics().skipped(0).end_bucket_elapsed_millis()); + EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); + + auto dropEvent = report.value_metrics().skipped(0).drop_event(0); + EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason()); + EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis()); +} + +/* + * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition + * change event (i.e. the condition change occurs in the wrong bucket). + */ +TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Condition change to true. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + // Condition change event. + valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); + + // Bucket boundary pull. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15)); + valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1); + + // Late condition change event. + valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100); + + // Check dump report. + ProtoOutputStream output; + std::set<string> strSet; + valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_TRUE(report.has_value_metrics()); + EXPECT_EQ(1, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().skipped_size()); + + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + report.value_metrics().skipped(0).start_bucket_elapsed_millis()); + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), + report.value_metrics().skipped(0).end_bucket_elapsed_millis()); + EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); + + auto dropEvent = report.value_metrics().skipped(0).drop_event(0); + EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason()); + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis()); +} + +/* + * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate + * event (i.e. the accumulate events call occurs in the wrong bucket). + */ +TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Condition change to true. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10)); + return true; + })) + // Dump report requested. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + // Condition change event. + valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); + + // Bucket boundary pull. + vector<shared_ptr<LogEvent>> allData; + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15)); + valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1); + + allData.clear(); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 20)); + + // Late accumulateEvents event. + valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100); + + // Check dump report. + ProtoOutputStream output; + std::set<string> strSet; + valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_TRUE(report.has_value_metrics()); + EXPECT_EQ(1, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().skipped_size()); + + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), + report.value_metrics().skipped(0).start_bucket_elapsed_millis()); + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), + report.value_metrics().skipped(0).end_bucket_elapsed_millis()); + EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); + + auto dropEvent = report.value_metrics().skipped(0).drop_event(0); + EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason()); + EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis()); +} + +/* + * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition + * when a metric is initialized. + */ +TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Condition change to true. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10)); + return true; + })) + // Dump report requested. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15)); + return true; + })); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager, + metric); + + // Condition change event. + valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); + + // Check dump report. + ProtoOutputStream output; + std::set<string> strSet; + int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_TRUE(report.has_value_metrics()); + EXPECT_EQ(0, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().skipped_size()); + + EXPECT_EQ(NanoToMillis(bucketStartTimeNs), + report.value_metrics().skipped(0).start_bucket_elapsed_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), + report.value_metrics().skipped(0).end_bucket_elapsed_millis()); + EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); + + auto dropEvent = report.value_metrics().skipped(0).drop_event(0); + EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); +} + +/* + * Test that PULL_FAILED dump reason is logged due to a pull failure in + * #pullAndMatchEventsLocked. + */ +TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) { + ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); + + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); + EXPECT_CALL(*pullerManager, Pull(tagId, _)) + // Condition change to true. + .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) { + data->clear(); + data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10)); + return true; + })) + // Dump report requested, pull fails. + .WillOnce(Return(false)); + + sp<ValueMetricProducer> valueProducer = + ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric); + + // Condition change event. + valueProducer->onConditionChanged(true, bucketStartTimeNs + 50); + + // Check dump report. + ProtoOutputStream output; + std::set<string> strSet; + int64_t dumpReportTimeNs = bucketStartTimeNs + 10000; + valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true, + NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output); + + StatsLogReport report = outputStreamToProto(&output); + EXPECT_TRUE(report.has_value_metrics()); + EXPECT_EQ(0, report.value_metrics().data_size()); + EXPECT_EQ(1, report.value_metrics().skipped_size()); + + EXPECT_EQ(NanoToMillis(bucketStartTimeNs), + report.value_metrics().skipped(0).start_bucket_elapsed_millis()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), + report.value_metrics().skipped(0).end_bucket_elapsed_millis()); + EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size()); + + auto dropEvent = report.value_metrics().skipped(0).drop_event(0); + EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason()); + EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis()); +} + ///* // * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event // * skips over more than one bucket. |