diff options
32 files changed, 121 insertions, 3235 deletions
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 6df0a8e14f6a..0ba36b3c8565 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -253,9 +253,6 @@ cc_test { "tests/e2e/GaugeMetric_e2e_push_test.cpp", "tests/e2e/GaugeMetric_e2e_pull_test.cpp", "tests/e2e/ValueMetric_pull_e2e_test.cpp", - "tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp", - "tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp", - "tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp", "tests/e2e/Anomaly_count_e2e_test.cpp", "tests/e2e/Anomaly_duration_sum_e2e_test.cpp", "tests/e2e/ConfigTtl_e2e_test.cpp", diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp index 60a4b236df11..52a1269798ca 100644 --- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp +++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp @@ -110,20 +110,14 @@ bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConf void CombinationConditionTracker::isConditionMet( const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions, - const std::vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { + vector<ConditionState>& conditionCache) const { // So far, this is fine as there is at most one child having sliced output. for (const int childIndex : mChildren) { if (conditionCache[childIndex] == ConditionState::kNotEvaluated) { allConditions[childIndex]->isConditionMet(conditionParameters, allConditions, - dimensionFields, - isSubOutputDimensionFields, isPartialLink, - conditionCache, - dimensionsKeySet); + conditionCache); } } conditionCache[mIndex] = @@ -178,25 +172,6 @@ void CombinationConditionTracker::evaluateCondition( } } -ConditionState CombinationConditionTracker::getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const std::vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { - vector<ConditionState> conditionCache(allConditions.size(), ConditionState::kNotEvaluated); - // So far, this is fine as there is at most one child having sliced output. - for (const int childIndex : mChildren) { - conditionCache[childIndex] = conditionCache[childIndex] | - allConditions[childIndex]->getMetConditionDimension( - allConditions, dimensionFields, isSubOutputDimensionFields, dimensionsKeySet); - } - evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache); - if (conditionCache[mIndex] == ConditionState::kTrue && dimensionsKeySet.empty()) { - dimensionsKeySet.insert(DEFAULT_DIMENSION_KEY); - } - return conditionCache[mIndex]; -} - bool CombinationConditionTracker::equalOutputDimensions( const std::vector<sp<ConditionTracker>>& allConditions, const vector<Matcher>& dimensions) const { diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h index 481cb200d8e6..e3d860127780 100644 --- a/cmds/statsd/src/condition/CombinationConditionTracker.h +++ b/cmds/statsd/src/condition/CombinationConditionTracker.h @@ -43,17 +43,8 @@ public: void isConditionMet(const ConditionKey& conditionParameters, const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - std::vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; - - ConditionState getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; + std::vector<ConditionState>& conditionCache) const override; // Only one child predicate can have dimension. const std::set<HashableDimensionKey>* getChangedToTrueDimensions( diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h index 1f4266b61cdf..e94ea6586f05 100644 --- a/cmds/statsd/src/condition/ConditionTracker.h +++ b/cmds/statsd/src/condition/ConditionTracker.h @@ -84,29 +84,14 @@ public: // condition. // [allConditions]: all condition trackers. This is needed because the condition evaluation is // done recursively - // [dimensionFields]: the needed dimension fields which should be all or subset of the condition - // tracker output dimension. - // [isSubOutputDimensionFields]: true if the needed dimension fields which is strictly subset of - // the condition tracker output dimension. // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields // in the condition tracker output dimension. // [conditionCache]: the cache holding the condition evaluation values. - // [dimensionsKeySet]: the dimensions where the sliced condition is true. For combination - // condition, it assumes that only one child predicate is sliced. virtual void isConditionMet( const ConditionKey& conditionParameters, const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - std::vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0; - - virtual ConditionState getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const = 0; + std::vector<ConditionState>& conditionCache) const = 0; // return the list of LogMatchingTracker index that this ConditionTracker uses. virtual const std::set<int>& getLogTrackerIndex() const { diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp index 23a9d371145e..4f44a69ba980 100644 --- a/cmds/statsd/src/condition/ConditionWizard.cpp +++ b/cmds/statsd/src/condition/ConditionWizard.cpp @@ -25,27 +25,15 @@ using std::string; using std::vector; ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - const bool isPartialLink, - std::unordered_set<HashableDimensionKey>* dimensionKeySet) { + const bool isPartialLink) { vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated); mAllConditions[index]->isConditionMet( - parameters, mAllConditions, dimensionFields, isSubOutputDimensionFields, isPartialLink, - cache, *dimensionKeySet); + parameters, mAllConditions, isPartialLink, + cache); return cache[index]; } -ConditionState ConditionWizard::getMetConditionDimension( - const int index, const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const { - return mAllConditions[index]->getMetConditionDimension(mAllConditions, dimensionFields, - isSubOutputDimensionFields, - *dimensionsKeySet); -} - const set<HashableDimensionKey>* ConditionWizard::getChangedToTrueDimensions( const int index) const { return mAllConditions[index]->getChangedToTrueDimensions(mAllConditions); @@ -82,4 +70,4 @@ bool ConditionWizard::equalOutputDimensions(const int index, const vector<Matche } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h index 2c8814772839..892647910d9f 100644 --- a/cmds/statsd/src/condition/ConditionWizard.h +++ b/cmds/statsd/src/condition/ConditionWizard.h @@ -40,15 +40,7 @@ public: // The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case, // the conditionParameters contains the parameters for it's children SimpleConditionTrackers. virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - const bool isPartialLink, - std::unordered_set<HashableDimensionKey>* dimensionKeySet); - - virtual ConditionState getMetConditionDimension( - const int index, const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>* dimensionsKeySet) const; + const bool isPartialLink); virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(const int index) const; virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions( diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp index 87104a34c009..0c92149f4c96 100644 --- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp +++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp @@ -344,11 +344,8 @@ void SimpleConditionTracker::evaluateCondition( void SimpleConditionTracker::isConditionMet( const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { + vector<ConditionState>& conditionCache) const { if (conditionCache[mIndex] != ConditionState::kNotEvaluated) { // it has been evaluated. @@ -360,18 +357,13 @@ void SimpleConditionTracker::isConditionMet( if (pair == conditionParameters.end()) { ConditionState conditionState = ConditionState::kNotEvaluated; - if (dimensionFields.size() > 0 && dimensionFields[0].mMatcher.getTag() == mDimensionTag) { - conditionState = conditionState | getMetConditionDimension( - allConditions, dimensionFields, isSubOutputDimensionFields, dimensionsKeySet); - } else { - conditionState = conditionState | mInitialValue; - if (!mSliced) { - const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY); - if (itr != mSlicedConditionState.end()) { - ConditionState sliceState = - itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse; - conditionState = conditionState | sliceState; - } + conditionState = conditionState | mInitialValue; + if (!mSliced) { + const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY); + if (itr != mSlicedConditionState.end()) { + ConditionState sliceState = + itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse; + conditionState = conditionState | sliceState; } } conditionCache[mIndex] = conditionState; @@ -389,15 +381,6 @@ void SimpleConditionTracker::isConditionMet( slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse; if (slice.first.contains(key)) { conditionState = conditionState | sliceState; - if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) { - if (isSubOutputDimensionFields) { - HashableDimensionKey dimensionKey; - filterValues(dimensionFields, slice.first.getValues(), &dimensionKey); - dimensionsKeySet.insert(dimensionKey); - } else { - dimensionsKeySet.insert(slice.first); - } - } } } } else { @@ -407,15 +390,6 @@ void SimpleConditionTracker::isConditionMet( ConditionState sliceState = startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse; conditionState = conditionState | sliceState; - if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) { - if (isSubOutputDimensionFields) { - HashableDimensionKey dimensionKey; - filterValues(dimensionFields, startedCountIt->first.getValues(), &dimensionKey); - dimensionsKeySet.insert(dimensionKey); - } else { - dimensionsKeySet.insert(startedCountIt->first); - } - } } } @@ -423,41 +397,6 @@ void SimpleConditionTracker::isConditionMet( VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]); } -ConditionState SimpleConditionTracker::getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { - ConditionState conditionState = mInitialValue; - if (dimensionFields.size() == 0 || mOutputDimensions.size() == 0 || - dimensionFields[0].mMatcher.getTag() != mOutputDimensions[0].mMatcher.getTag()) { - const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY); - if (itr != mSlicedConditionState.end()) { - ConditionState sliceState = - itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse; - conditionState = conditionState | sliceState; - } - return conditionState; - } - - for (const auto& slice : mSlicedConditionState) { - ConditionState sliceState = - slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse; - conditionState = conditionState | sliceState; - - if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) { - if (isSubOutputDimensionFields) { - HashableDimensionKey dimensionKey; - filterValues(dimensionFields, slice.first.getValues(), &dimensionKey); - dimensionsKeySet.insert(dimensionKey); - } else { - dimensionsKeySet.insert(slice.first); - } - } - } - return conditionState; -} - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h index 47d1eceb9022..5c5cc565f783 100644 --- a/cmds/statsd/src/condition/SimpleConditionTracker.h +++ b/cmds/statsd/src/condition/SimpleConditionTracker.h @@ -48,17 +48,8 @@ public: void isConditionMet(const ConditionKey& conditionParameters, const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - std::vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; - - ConditionState getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; + std::vector<ConditionState>& conditionCache) const override; virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions( const std::vector<sp<ConditionTracker>>& allConditions) const { diff --git a/cmds/statsd/src/condition/StateTracker.cpp b/cmds/statsd/src/condition/StateTracker.cpp index 1965ce6015ff..18c7178dd7d7 100644 --- a/cmds/statsd/src/condition/StateTracker.cpp +++ b/cmds/statsd/src/condition/StateTracker.cpp @@ -178,11 +178,8 @@ void StateTracker::evaluateCondition(const LogEvent& event, void StateTracker::isConditionMet( const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { + vector<ConditionState>& conditionCache) const { if (conditionCache[mIndex] != ConditionState::kNotEvaluated) { // it has been evaluated. VLOG("Yes, already evaluated, %lld %d", (long long)mConditionId, conditionCache[mIndex]); @@ -193,10 +190,6 @@ void StateTracker::isConditionMet( if (pair == conditionParameters.end()) { if (mSlicedState.size() > 0) { conditionCache[mIndex] = ConditionState::kTrue; - - for (const auto& state : mSlicedState) { - dimensionsKeySet.insert(state.second); - } } else { conditionCache[mIndex] = ConditionState::kUnknown; } @@ -208,25 +201,9 @@ void StateTracker::isConditionMet( auto it = mSlicedState.find(primaryKey); if (it != mSlicedState.end()) { conditionCache[mIndex] = ConditionState::kTrue; - dimensionsKeySet.insert(it->second); - } -} - -ConditionState StateTracker::getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const { - if (mSlicedState.size() > 0) { - for (const auto& state : mSlicedState) { - dimensionsKeySet.insert(state.second); - } - return ConditionState::kTrue; } - - return mInitialValue; } } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/condition/StateTracker.h b/cmds/statsd/src/condition/StateTracker.h index 2bdf98c34c32..5ae4441713cd 100644 --- a/cmds/statsd/src/condition/StateTracker.h +++ b/cmds/statsd/src/condition/StateTracker.h @@ -55,22 +55,8 @@ public: */ void isConditionMet(const ConditionKey& conditionParameters, const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, const bool isPartialLink, - std::vector<ConditionState>& conditionCache, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; - - /** - * Note: dimensionFields will be ignored in StateTracker, because we demand metrics - * must take the entire dimension fields from StateTracker. This is to make implementation - * simple and efficient. - */ - ConditionState getMetConditionDimension( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensionFields, - const bool isSubOutputDimensionFields, - std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; + std::vector<ConditionState>& conditionCache) const override; virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions( const std::vector<sp<ConditionTracker>>& allConditions) const { @@ -128,4 +114,4 @@ private: } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index c023e6f77e7c..23d025f82c26 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -48,7 +48,6 @@ const int FIELD_ID_COUNT_METRICS = 5; const int FIELD_ID_TIME_BASE = 9; const int FIELD_ID_BUCKET_SIZE = 10; const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11; -const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12; const int FIELD_ID_IS_ACTIVE = 14; // for CountMetricDataWrapper @@ -82,12 +81,7 @@ CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what()); } - mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) || - HasPositionALL(metric.dimensions_in_condition()); - - if (metric.has_dimensions_in_condition()) { - translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition); - } + mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); if (metric.links().size() > 0) { for (const auto& link : metric.links()) { @@ -100,8 +94,6 @@ CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric mConditionSliced = true; } - mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0); - flushIfNeededLocked(startTimeNs); // Adjust start for partial bucket mCurrentBucketStartTimeNs = startTimeNs; @@ -171,13 +163,6 @@ void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, writeDimensionPathToProto(mDimensionsInWhat, protoOutput); protoOutput->end(dimenPathToken); } - if (!mDimensionsInCondition.empty()) { - uint64_t dimenPathToken = protoOutput->start( - FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION); - writeDimensionPathToProto(mDimensionsInCondition, protoOutput); - protoOutput->end(dimenPathToken); - } - } uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS); diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index 96fbf7fb5ebe..cca793b2146a 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -47,7 +47,6 @@ const int FIELD_ID_DURATION_METRICS = 6; const int FIELD_ID_TIME_BASE = 9; const int FIELD_ID_BUCKET_SIZE = 10; const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11; -const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12; const int FIELD_ID_IS_ACTIVE = 14; // for DurationMetricDataWrapper const int FIELD_ID_DATA = 1; @@ -100,12 +99,7 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat ALOGE("Position ANY in dimension_in_what not supported."); } - if (metric.has_dimensions_in_condition()) { - translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition); - } - - mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) || - HasPositionALL(metric.dimensions_in_condition()); + mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); if (metric.links().size() > 0) { for (const auto& link : metric.links()) { @@ -115,19 +109,16 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields); mMetric2ConditionLinks.push_back(mc); } + mConditionSliced = true; } - mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0); mUnSlicedPartCondition = ConditionState::kUnknown; mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions); - if (mWizard != nullptr && mConditionTrackerIndex >= 0) { - mSameConditionDimensionsInTracker = - mWizard->equalOutputDimensions(mConditionTrackerIndex, mDimensionsInCondition); - if (mMetric2ConditionLinks.size() == 1) { - mHasLinksToAllConditionDimensionsInTracker = - mWizard->equalOutputDimensions(mConditionTrackerIndex, - mMetric2ConditionLinks.begin()->conditionFields); - } + if (mWizard != nullptr && mConditionTrackerIndex >= 0 && + mMetric2ConditionLinks.size() == 1) { + mHasLinksToAllConditionDimensionsInTracker = + mWizard->equalOutputDimensions(mConditionTrackerIndex, + mMetric2ConditionLinks.begin()->conditionFields); } flushIfNeededLocked(startTimeNs); // Adjust start for partial bucket @@ -164,13 +155,13 @@ unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker( case DurationMetric_AggregationType_SUM: return make_unique<OringDurationTracker>( mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, - mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum, + mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs, mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers); case DurationMetric_AggregationType_MAX_SPARSE: return make_unique<MaxDurationTracker>( mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, - mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum, + mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs, mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers); } @@ -178,13 +169,11 @@ unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker( // SlicedConditionChange optimization case 1: // 1. If combination condition, logical operation is AND, only one sliced child predicate. -// 2. No condition in dimension -// 3. The links covers all dimension fields in the sliced child condition predicate. +// 2. The links covers all dimension fields in the sliced child condition predicate. void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition, const int64_t eventTime) { if (mMetric2ConditionLinks.size() != 1 || - !mHasLinksToAllConditionDimensionsInTracker || - !mDimensionsInCondition.empty()) { + !mHasLinksToAllConditionDimensionsInTracker) { return; } @@ -249,178 +238,20 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool conditio } } - -// SlicedConditionChange optimization case 2: -// 1. If combination condition, logical operation is AND, only one sliced child predicate. -// 2. Has dimensions_in_condition and it equals to the output dimensions of the sliced predicate. -void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool condition, - const int64_t eventTime) { - if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) { - return; - } - - auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex); - auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex); - - bool currentUnSlicedPartCondition = true; - if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) { - ConditionState unslicedPartState = - mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex); - // When the unsliced part is still false, return directly. - if (mUnSlicedPartCondition == ConditionState::kFalse && - unslicedPartState == ConditionState::kFalse) { - return; - } - mUnSlicedPartCondition = unslicedPartState; - currentUnSlicedPartCondition = mUnSlicedPartCondition > 0; - } - - const std::set<HashableDimensionKey>* trueDimensionsToProcess = nullptr; - const std::set<HashableDimensionKey>* falseDimensionsToProcess = nullptr; - - std::set<HashableDimensionKey> currentTrueConditionDimensions; - if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr || - (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) { - mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, ¤tTrueConditionDimensions); - trueDimensionsToProcess = ¤tTrueConditionDimensions; - } else if (currentUnSlicedPartCondition) { - // Handles the condition change from the sliced predicate. If the unsliced condition state - // is not true, not need to do anything. - trueDimensionsToProcess = dimensionsChangedToTrue; - falseDimensionsToProcess = dimensionsChangedToFalse; - } - - if (trueDimensionsToProcess == nullptr && falseDimensionsToProcess == nullptr) { - return; - } - - for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { - if (falseDimensionsToProcess != nullptr) { - for (const auto& changedDim : *falseDimensionsToProcess) { - auto condIt = whatIt.second.find(changedDim); - if (condIt != whatIt.second.end()) { - condIt->second->onConditionChanged(false, eventTime); - } - } - } - if (trueDimensionsToProcess != nullptr) { - HashableDimensionKey linkedConditionDimensionKey; - if (!trueDimensionsToProcess->empty() && mMetric2ConditionLinks.size() == 1) { - getDimensionForCondition(whatIt.first.getValues(), - mMetric2ConditionLinks[0], - &linkedConditionDimensionKey); - } - for (auto& trueDim : *trueDimensionsToProcess) { - auto condIt = whatIt.second.find(trueDim); - if (condIt != whatIt.second.end()) { - condIt->second->onConditionChanged( - currentUnSlicedPartCondition, eventTime); - } else { - if (mMetric2ConditionLinks.size() == 0 || - trueDim.contains(linkedConditionDimensionKey)) { - if (!whatIt.second.empty()) { - auto newEventKey = MetricDimensionKey(whatIt.first, trueDim); - if (hitGuardRailLocked(newEventKey)) { - continue; - } - unique_ptr<DurationTracker> newTracker = - whatIt.second.begin()->second->clone(eventTime); - if (newTracker != nullptr) { - newTracker->setEventKey(newEventKey); - newTracker->onConditionChanged(true, eventTime); - whatIt.second[trueDim] = std::move(newTracker); - } - } - } - } - } - } - } -} - void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition, const int64_t eventTimeNs) { bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex); - if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker && - mDimensionsInCondition.empty()) { + if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker) { onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs); return; } - if (changeDimTrackable && mSameConditionDimensionsInTracker && - mMetric2ConditionLinks.size() <= 1) { - onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTimeNs); - return; - } - // Now for each of the on-going event, check if the condition has changed for them. for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { for (auto& pair : whatIt.second) { pair.second->onSlicedConditionMayChange(overallCondition, eventTimeNs); } } - - if (mDimensionsInCondition.empty()) { - return; - } - - if (mMetric2ConditionLinks.empty()) { - std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet; - mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition, - !mSameConditionDimensionsInTracker, - &conditionDimensionsKeySet); - for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) { - for (const auto& pair : whatIt.second) { - conditionDimensionsKeySet.erase(pair.first); - } - } - for (const auto& conditionDimension : conditionDimensionsKeySet) { - for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { - if (!whatIt.second.empty()) { - auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension); - if (hitGuardRailLocked(newEventKey)) { - continue; - } - unique_ptr<DurationTracker> newTracker = - whatIt.second.begin()->second->clone(eventTimeNs); - if (newTracker != nullptr) { - newTracker->setEventKey(MetricDimensionKey(newEventKey)); - newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs); - whatIt.second[conditionDimension] = std::move(newTracker); - } - } - } - } - } else { - for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { - ConditionKey conditionKey; - for (const auto& link : mMetric2ConditionLinks) { - getDimensionForCondition(whatIt.first.getValues(), link, - &conditionKey[link.conditionId]); - } - std::unordered_set<HashableDimensionKey> conditionDimensionsKeys; - mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &conditionDimensionsKeys); - - for (const auto& conditionDimension : conditionDimensionsKeys) { - if (!whatIt.second.empty() && - whatIt.second.find(conditionDimension) == whatIt.second.end()) { - auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension); - if (hitGuardRailLocked(newEventKey)) { - continue; - } - auto newTracker = whatIt.second.begin()->second->clone(eventTimeNs); - if (newTracker != nullptr) { - newTracker->setEventKey(newEventKey); - newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs); - whatIt.second[conditionDimension] = std::move(newTracker); - } - } - } - } - } } void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition, @@ -526,12 +357,6 @@ void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, writeDimensionPathToProto(mDimensionsInWhat, protoOutput); protoOutput->end(dimenPathToken); } - if (!mDimensionsInCondition.empty()) { - uint64_t dimenPathToken = protoOutput->start( - FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION); - writeDimensionPathToProto(mDimensionsInCondition, protoOutput); - protoOutput->end(dimenPathToken); - } } uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS); @@ -790,52 +615,24 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, bool condition; ConditionKey conditionKey; - std::unordered_set<HashableDimensionKey> dimensionKeysInCondition; if (mConditionSliced) { for (const auto& link : mMetric2ConditionLinks) { getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]); } auto conditionState = - mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &dimensionKeysInCondition); + mWizard->query(mConditionTrackerIndex, conditionKey, + !mHasLinksToAllConditionDimensionsInTracker); condition = conditionState == ConditionState::kTrue; - if (mDimensionsInCondition.empty() && condition) { - dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); - } } else { // TODO: The unknown condition state is not handled here, we should fix it. condition = mCondition == ConditionState::kTrue; - if (condition) { - dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); - } } condition = condition && mIsActive; - if (dimensionKeysInCondition.empty()) { - handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY), - conditionKey, condition, event); - } else { - auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat); - // If the what dimension is already there, we should update all the trackers even - // the condition is false. - if (whatIt != mCurrentSlicedDurationTrackerMap.end()) { - for (const auto& condIt : whatIt->second) { - const bool cond = dimensionKeysInCondition.find(condIt.first) != - dimensionKeysInCondition.end() && condition; - handleStartEvent(MetricDimensionKey(dimensionInWhat, condIt.first), - conditionKey, cond, event); - dimensionKeysInCondition.erase(condIt.first); - } - } - for (const auto& conditionDimension : dimensionKeysInCondition) { - handleStartEvent(MetricDimensionKey(dimensionInWhat, conditionDimension), conditionKey, - condition, event); - } - } + handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY), + conditionKey, condition, event); } size_t DurationMetricProducer::byteSizeLocked() const { diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index a64bbc1056e0..1f423cd384ef 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -48,7 +48,6 @@ const int FIELD_ID_GAUGE_METRICS = 8; const int FIELD_ID_TIME_BASE = 9; const int FIELD_ID_BUCKET_SIZE = 10; const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11; -const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12; const int FIELD_ID_IS_ACTIVE = 14; // for GaugeMetricDataWrapper const int FIELD_ID_DATA = 1; @@ -115,10 +114,6 @@ GaugeMetricProducer::GaugeMetricProducer( mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what()); } - if (metric.has_dimensions_in_condition()) { - translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition); - } - if (metric.links().size() > 0) { for (const auto& link : metric.links()) { Metric2Condition mc; @@ -127,10 +122,9 @@ GaugeMetricProducer::GaugeMetricProducer( translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields); mMetric2ConditionLinks.push_back(mc); } + mConditionSliced = true; } - mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0); - mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) || - HasPositionALL(metric.dimensions_in_condition()); + mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); flushIfNeededLocked(startTimeNs); // Kicks off the puller immediately. @@ -209,12 +203,6 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, writeDimensionPathToProto(mDimensionsInWhat, protoOutput); protoOutput->end(dimenPathToken); } - if (!mDimensionsInCondition.empty()) { - uint64_t dimenPathToken = protoOutput->start( - FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION); - writeDimensionPathToProto(mDimensionsInCondition, protoOutput); - protoOutput->end(dimenPathToken); - } } uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS); diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp index 92752b29ecda..1ab4fdf6e90c 100644 --- a/cmds/statsd/src/metrics/MetricProducer.cpp +++ b/cmds/statsd/src/metrics/MetricProducer.cpp @@ -52,38 +52,24 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo bool condition; ConditionKey conditionKey; - std::unordered_set<HashableDimensionKey> dimensionKeysInCondition; if (mConditionSliced) { for (const auto& link : mMetric2ConditionLinks) { getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]); } auto conditionState = - mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &dimensionKeysInCondition); + mWizard->query(mConditionTrackerIndex, conditionKey, + !mHasLinksToAllConditionDimensionsInTracker); condition = (conditionState == ConditionState::kTrue); } else { // TODO: The unknown condition state is not handled here, we should fix it. condition = mCondition == ConditionState::kTrue; } - if (mDimensionsInCondition.empty() && condition) { - dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); - } - HashableDimensionKey dimensionInWhat; filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat); MetricDimensionKey metricKey(dimensionInWhat, DEFAULT_DIMENSION_KEY); - for (const auto& conditionDimensionKey : dimensionKeysInCondition) { - metricKey.setDimensionKeyInCondition(conditionDimensionKey); - onMatchedLogEventInternalLocked( - matcherIndex, metricKey, conditionKey, condition, event); - } - if (dimensionKeysInCondition.empty()) { - onMatchedLogEventInternalLocked( - matcherIndex, metricKey, conditionKey, condition, event); - } + onMatchedLogEventInternalLocked( + matcherIndex, metricKey, conditionKey, condition, event); } bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) { diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 09ad2903fa4c..94f833b20814 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -88,7 +88,6 @@ public: mConditionTrackerIndex(conditionIndex), mContainANYPositionInDimensionsInWhat(false), mSliceByPositionALL(false), - mSameConditionDimensionsInTracker(false), mHasLinksToAllConditionDimensionsInTracker(false), mIsActive(true) { } @@ -349,15 +348,10 @@ protected: int mConditionTrackerIndex; vector<Matcher> mDimensionsInWhat; // The dimensions_in_what defined in statsd_config - vector<Matcher> mDimensionsInCondition; // The dimensions_in_condition defined in statsd_config bool mContainANYPositionInDimensionsInWhat; bool mSliceByPositionALL; - // True iff the condition dimensions equal to the sliced dimensions in the simple condition - // tracker. This field is always false for combinational condition trackers. - bool mSameConditionDimensionsInTracker; - // True iff the metric to condition links cover all dimension fields in the condition tracker. // This field is always false for combinational condition trackers. bool mHasLinksToAllConditionDimensionsInTracker; diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 8efca1e10de5..3dad61465416 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -260,17 +260,6 @@ private: FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); - FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition); - - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition); - FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index 0e33a0f9f29b..bc1602497c39 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -51,7 +51,6 @@ const int FIELD_ID_VALUE_METRICS = 7; const int FIELD_ID_TIME_BASE = 9; const int FIELD_ID_BUCKET_SIZE = 10; const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11; -const int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12; const int FIELD_ID_IS_ACTIVE = 14; // for ValueMetricDataWrapper const int FIELD_ID_DATA = 1; @@ -127,10 +126,6 @@ ValueMetricProducer::ValueMetricProducer( mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what()); } - if (metric.has_dimensions_in_condition()) { - translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition); - } - if (metric.links().size() > 0) { for (const auto& link : metric.links()) { Metric2Condition mc; @@ -139,11 +134,10 @@ ValueMetricProducer::ValueMetricProducer( translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields); mMetric2ConditionLinks.push_back(mc); } + mConditionSliced = true; } - mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0); - mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) || - HasPositionALL(metric.dimensions_in_condition()); + mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs); mCurrentBucketNum += numBucketsForward; @@ -243,12 +237,6 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, writeDimensionPathToProto(mDimensionsInWhat, protoOutput); protoOutput->end(dimenPathToken); } - if (!mDimensionsInCondition.empty()) { - uint64_t dimenPathToken = - protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION); - writeDimensionPathToProto(mDimensionsInCondition, protoOutput); - protoOutput->end(dimenPathToken); - } } uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS); diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h index 081e61ed21fa..6b5c2994a0c8 100644 --- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h +++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h @@ -60,7 +60,7 @@ class DurationTracker { public: DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard, int conditionIndex, - const std::vector<Matcher>& dimensionInCondition, bool nesting, + bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink, const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers) @@ -70,7 +70,6 @@ public: mWizard(wizard), mConditionTrackerIndex(conditionIndex), mBucketSizeNs(bucketSizeNs), - mDimensionInCondition(dimensionInCondition), mNested(nesting), mCurrentBucketStartTimeNs(currentBucketStartNs), mDuration(0), @@ -180,8 +179,6 @@ protected: const int64_t mBucketSizeNs; - const std::vector<Matcher>& mDimensionInCondition; - const bool mNested; int64_t mCurrentBucketStartTimeNs; @@ -196,7 +193,6 @@ protected: const bool mConditionSliced; - bool mSameConditionDimensionsInTracker; bool mHasLinksToAllConditionDimensionsInTracker; std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers; diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp index 6868b8c24c71..df66cb0c53e5 100644 --- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp +++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp @@ -27,18 +27,14 @@ namespace statsd { MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard, int conditionIndex, - const vector<Matcher>& dimensionInCondition, bool nesting, + bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink, const vector<sp<DurationAnomalyTracker>>& anomalyTrackers) - : DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting, + : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs, currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink, anomalyTrackers) { - if (mWizard != nullptr) { - mSameConditionDimensionsInTracker = - mWizard->equalOutputDimensions(conditionIndex, mDimensionInCondition); - } } unique_ptr<DurationTracker> MaxDurationTracker::clone(const int64_t eventTime) { @@ -252,17 +248,11 @@ void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition, if (pair.second.state == kStopped) { continue; } - std::unordered_set<HashableDimensionKey> conditionDimensionKeySet; ConditionState conditionState = mWizard->query( - mConditionTrackerIndex, pair.second.conditionKeys, mDimensionInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &conditionDimensionKeySet); - bool conditionMet = - (conditionState == ConditionState::kTrue) && - (mDimensionInCondition.size() == 0 || - conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) != - conditionDimensionKeySet.end()); + mConditionTrackerIndex, pair.second.conditionKeys, + !mHasLinksToAllConditionDimensionsInTracker); + bool conditionMet = (conditionState == ConditionState::kTrue); + VLOG("key: %s, condition: %d", pair.first.toString().c_str(), conditionMet); noteConditionChanged(pair.first, conditionMet, timestamp); } diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h index 8e8f2cd6c582..d0371da096ea 100644 --- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h +++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h @@ -30,7 +30,7 @@ class MaxDurationTracker : public DurationTracker { public: MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard, int conditionIndex, - const std::vector<Matcher>& dimensionInCondition, bool nesting, + bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink, diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp index 956383a99eea..b0fd975b2328 100644 --- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp +++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp @@ -26,20 +26,16 @@ using std::pair; OringDurationTracker::OringDurationTracker( const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey, - sp<ConditionWizard> wizard, int conditionIndex, const vector<Matcher>& dimensionInCondition, + sp<ConditionWizard> wizard, int conditionIndex, bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink, const vector<sp<DurationAnomalyTracker>>& anomalyTrackers) - : DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting, + : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs, currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink, anomalyTrackers), mStarted(), mPaused() { mLastStartTime = 0; - if (mWizard != nullptr) { - mSameConditionDimensionsInTracker = - mWizard->equalOutputDimensions(conditionIndex, mDimensionInCondition); - } } unique_ptr<DurationTracker> OringDurationTracker::clone(const int64_t eventTime) { @@ -227,17 +223,10 @@ void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition, ++it; continue; } - std::unordered_set<HashableDimensionKey> conditionDimensionKeySet; ConditionState conditionState = mWizard->query(mConditionTrackerIndex, condIt->second, - mDimensionInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &conditionDimensionKeySet); - if (conditionState != ConditionState::kTrue || - (mDimensionInCondition.size() != 0 && - conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) == - conditionDimensionKeySet.end())) { + !mHasLinksToAllConditionDimensionsInTracker); + if (conditionState != ConditionState::kTrue) { startedToPaused.push_back(*it); it = mStarted.erase(it); VLOG("Key %s started -> paused", key.toString().c_str()); @@ -262,17 +251,10 @@ void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition, ++it; continue; } - std::unordered_set<HashableDimensionKey> conditionDimensionKeySet; ConditionState conditionState = mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key], - mDimensionInCondition, - !mSameConditionDimensionsInTracker, - !mHasLinksToAllConditionDimensionsInTracker, - &conditionDimensionKeySet); - if (conditionState == ConditionState::kTrue && - (mDimensionInCondition.size() == 0 || - conditionDimensionKeySet.find(mEventKey.getDimensionKeyInCondition()) != - conditionDimensionKeySet.end())) { + !mHasLinksToAllConditionDimensionsInTracker); + if (conditionState == ConditionState::kTrue) { pausedToStarted.push_back(*it); it = mPaused.erase(it); VLOG("Key %s paused -> started", key.toString().c_str()); diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h index 8e73256d4a01..43c48d5f536b 100644 --- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h +++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h @@ -29,7 +29,7 @@ class OringDurationTracker : public DurationTracker { public: OringDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard, - int conditionIndex, const std::vector<Matcher>& dimensionInCondition, + int conditionIndex, bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink, diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp index e826a52c2f33..6eaa2311e5ed 100644 --- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp +++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp @@ -268,8 +268,6 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) { std::vector<sp<ConditionTracker>> allConditions; for (Position position : { Position::FIRST, Position::LAST}) { - vector<Matcher> dimensionInCondition; - std::unordered_set<HashableDimensionKey> dimensionKeys; SimplePredicate simplePredicate = getWakeLockHeldCondition( true /*nesting*/, true /*default to false*/, true /*output slice by uid*/, @@ -321,9 +319,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) { const auto queryKey = getWakeLockQueryKey(position, uids, conditionName); conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); // another wake lock acquired by this uid @@ -389,9 +387,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) { // query again conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); } @@ -399,8 +397,6 @@ TEST(SimpleConditionTrackerTest, TestSlicedCondition) { TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) { std::vector<sp<ConditionTracker>> allConditions; - vector<Matcher> dimensionInCondition; - std::unordered_set<HashableDimensionKey> dimensionKeys; SimplePredicate simplePredicate = getWakeLockHeldCondition( true /*nesting*/, true /*default to false*/, false /*slice output by uid*/, @@ -445,9 +441,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) { ConditionKey queryKey; conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - true, true, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + true, + conditionCache); EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); // another wake lock acquired by this uid @@ -489,10 +485,9 @@ TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) { // query again conditionCache[0] = ConditionState::kNotEvaluated; - dimensionKeys.clear(); - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - true, true, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + true, + conditionCache); EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); } @@ -500,8 +495,6 @@ TEST(SimpleConditionTrackerTest, TestStopAll) { std::vector<sp<ConditionTracker>> allConditions; for (Position position : { Position::FIRST, Position::LAST }) { - vector<Matcher> dimensionInCondition; - std::unordered_set<HashableDimensionKey> dimensionKeys; SimplePredicate simplePredicate = getWakeLockHeldCondition( true /*nesting*/, true /*default to false*/, true /*output slice by uid*/, position); @@ -555,9 +548,9 @@ TEST(SimpleConditionTrackerTest, TestStopAll) { const auto queryKey = getWakeLockQueryKey(position, uid_list1, conditionName); conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); // another wake lock acquired by uid2 @@ -594,9 +587,9 @@ TEST(SimpleConditionTrackerTest, TestStopAll) { // TEST QUERY const auto queryKey2 = getWakeLockQueryKey(position, uid_list2, conditionName); conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kTrue, conditionCache[0]); @@ -628,17 +621,17 @@ TEST(SimpleConditionTrackerTest, TestStopAll) { // TEST QUERY const auto queryKey3 = getWakeLockQueryKey(position, uid_list1, conditionName); conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); // TEST QUERY const auto queryKey4 = getWakeLockQueryKey(position, uid_list2, conditionName); conditionCache[0] = ConditionState::kNotEvaluated; - conditionTracker.isConditionMet(queryKey, allPredicates, dimensionInCondition, - false, false, - conditionCache, dimensionKeys); + conditionTracker.isConditionMet(queryKey, allPredicates, + false, + conditionCache); EXPECT_EQ(ConditionState::kFalse, conditionCache[0]); } } diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp deleted file mode 100644 index e4186b7200a0..000000000000 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp +++ /dev/null @@ -1,961 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <gtest/gtest.h> - -#include "src/StatsLogProcessor.h" -#include "src/stats_log_util.h" -#include "tests/statsd_test_util.h" - -#include <vector> - -namespace android { -namespace os { -namespace statsd { - -#ifdef __ANDROID__ - -namespace { - -StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition( - DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition, - bool hashStringInReport) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED); - dimensions->add_child()->set_field(2); // job name field. - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED, - {Position::FIRST}); - if (addExtraDimensionInCondition) { - syncDimension->add_child()->set_field(2 /* name field*/); - } - - config.set_hash_strings_in_metric_report(hashStringInReport); - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(StringToId("CombinationPredicate")); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(combinationPredicate->id()); - metric->set_aggregation_type(aggregationType); - auto dimensionWhat = metric->mutable_dimensions_in_what(); - dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED); - dimensionWhat->add_child()->set_field(2); // job name field. - *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -/* - The following test has the following input. - -{ 10000000002 10000000002 (8)9999[I], [S], job0[S], 1[I], } -{ 10000000010 10000000010 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I], } -{ 10000000011 10000000011 (29)1[I], } -{ 10000000040 10000000040 (29)2[I], } -{ 10000000050 10000000050 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I], } -{ 10000000101 10000000101 (8)9999[I], [S], job0[S], 0[I], } -{ 10000000102 10000000102 (29)1[I], } -{ 10000000200 10000000200 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 1[I], } -{ 10000000201 10000000201 (8)9999[I], [S], job2[S], 1[I], } -{ 10000000400 10000000400 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 1[I], } -{ 10000000401 10000000401 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 1[I], } -{ 10000000450 10000000450 (29)2[I], } -{ 10000000500 10000000500 (8)9999[I], [S], job2[S], 0[I], } -{ 10000000600 10000000600 (8)8888[I], [S], job2[S], 1[I], } -{ 10000000650 10000000650 (29)1[I], } -{ 309999999999 309999999999 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadDoc[S], 0[I], } -{ 310000000100 310000000100 (29)2[I], } -{ 310000000300 310000000300 (7)111[I], App1[S], 222[I], GMSCoreModule1[S], 222[I], GMSCoreModule2[S], ReadEmail[S], 0[I], } -{ 310000000600 310000000600 (8)8888[I], [S], job1[S], 1[I], } -{ 310000000640 310000000640 (29)1[I], } -{ 310000000650 310000000650 (29)2[I], } -{ 310000000700 310000000700 (7)333[I], App2[S], 222[I], GMSCoreModule1[S], 555[I], GMSCoreModule2[S], ReadEmail[S], 0[I], } -{ 310000000850 310000000850 (8)8888[I], [S], job2[S], 0[I], } -{ 310000000900 310000000900 (8)8888[I], [S], job1[S], 0[I], } -*/ -TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition) { - for (const bool hashStringInReport : { true, false }) { - for (bool isDimensionInConditionSubSetOfConditionTrackerDimension : { true, false }) { - for (auto aggregationType : {DurationMetric::MAX_SPARSE, DurationMetric::SUM}) { - ConfigKey cfgKey; - auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition( - aggregationType, isDimensionInConditionSubSetOfConditionTrackerDimension, - hashStringInReport); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis( - config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 11)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 40)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 102)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 450)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 650)); - events.push_back(CreateScreenStateChangedEvent( - android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + bucketSizeNs + 100)); - - events.push_back(CreateScreenStateChangedEvent( - android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + bucketSizeNs + 640)); - events.push_back(CreateScreenStateChangedEvent( - android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + bucketSizeNs + 650)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(9999, "")}, "job0", bucketStartTimeNs + 2)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(9999, "")}, "job0",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(9999, "")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(9999, "")}, "job2",bucketStartTimeNs + 500)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(8888, "")}, "job2", bucketStartTimeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(8888, "")}, "job2", - bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(8888, "")}, "job1", - bucketStartTimeNs + bucketSizeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(8888, "")}, "job1", - bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 10)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 200)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 300)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 401)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, - true, ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job0"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40 - 11); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - - data = metrics.data(1); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job1"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 10); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201 + bucketSizeNs - 650); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401 + bucketSizeNs - 650); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100 + 650 - 640); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job0"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40 - 11); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job1"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 10); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 201); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple(). - dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension( - data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 401); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 650 + 110); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } - } - } -} - -namespace { - -StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition( - DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - *dimensions = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - dimensions->add_child()->set_field(2); // job name field. - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - if (addExtraDimensionInCondition) { - syncDimension->add_child()->set_field(2 /* name field*/); - } - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(StringToId("CombinationPredicate")); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(combinationPredicate->id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - *links->mutable_fields_in_what() = - CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition) { - for (bool isFullLink : {true, false}) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition( - aggregationType, !isFullLink); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions3 = { - CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 55)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 120)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 121)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 450)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 501)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + bucketSizeNs + 100)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500)); - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", - bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back( - CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs - 2)); - events.push_back( - CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 110)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 300)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 550)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 800)); - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, - true, ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } - } -} - -namespace { - -StatsdConfig CreateDurationMetricConfig_PartialLink_AND_CombinationCondition( - DurationMetric::AggregationType aggregationType, bool hashStringInReport) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - *dimensions = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - dimensions->add_child()->set_field(2); // job name field. - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - syncDimension->add_child()->set_field(2 /* name field*/); - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - - config.set_hash_strings_in_metric_report(hashStringInReport); - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(StringToId("CombinationPredicate")); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(combinationPredicate->id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *metric->mutable_dimensions_in_condition() = *syncDimension; - - - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - *links->mutable_fields_in_what() = - CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition) { - for (const bool hashStringInReport : {true, false}) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = - CreateDurationMetricConfig_PartialLink_AND_CombinationCondition( - aggregationType, hashStringInReport); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions3 = { - CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 55)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 120)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 121)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 450)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 501)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + bucketSizeNs + 100)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500)); - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", - bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back( - CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs - 2)); - events.push_back( - CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 110)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 300)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 550)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 800)); - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, - true, ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 1 - 600 + 50); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 55); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 50); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 1 - 600); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 450 - 300); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple(). - dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } - } -} - -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp deleted file mode 100644 index f3ecd56dd946..000000000000 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp +++ /dev/null @@ -1,816 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <gtest/gtest.h> - -#include "src/StatsLogProcessor.h" -#include "src/stats_log_util.h" -#include "tests/statsd_test_util.h" - -#include <vector> - -namespace android { -namespace os { -namespace statsd { - -#ifdef __ANDROID__ - -namespace { - -StatsdConfig CreateCountMetric_NoLink_CombinationCondition_Config() { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - auto screenBrightnessChangeAtomMatcher = CreateScreenBrightnessChangedAtomMatcher(); - *config.add_atom_matcher() = screenBrightnessChangeAtomMatcher; - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher(); - *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher(); - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - *config.add_predicate() = screenIsOffPredicate; - - auto holdingWakelockPredicate = CreateHoldingWakelockPredicate(); - // The predicate is dimensioning by any attribution node and both by uid and tag. - *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = - CreateAttributionUidAndTagDimensions(android::util::WAKELOCK_STATE_CHANGED, - {Position::FIRST}); - *config.add_predicate() = holdingWakelockPredicate; - - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(987654); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(holdingWakelockPredicate, combinationPredicate); - - auto metric = config.add_count_metric(); - metric->set_id(StringToId("ScreenBrightnessChangeMetric")); - metric->set_what(screenBrightnessChangeAtomMatcher.id()); - metric->set_condition(combinationPredicate->id()); - *metric->mutable_dimensions_in_what() = - CreateDimensions(android::util::SCREEN_BRIGHTNESS_CHANGED, {1 /* level */}); - *metric->mutable_dimensions_in_condition() = CreateAttributionUidDimensions( - android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST}); - metric->set_bucket(FIVE_MINUTES); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition) { - ConfigKey cfgKey; - auto config = CreateCountMetric_NoLink_CombinationCondition_Config(); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"), - CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"), - CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - events.push_back( - CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 100)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + bucketSizeNs + 1)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 2 * bucketSizeNs - 10)); - - events.push_back(CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 200)); - events.push_back( - CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 1)); - - events.push_back(CreateAcquireWakelockEvent(attributions2, "wl2", - bucketStartTimeNs + bucketSizeNs - 100)); - events.push_back(CreateReleaseWakelockEvent(attributions2, "wl2", - bucketStartTimeNs + 2 * bucketSizeNs - 50)); - - events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 11)); - events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 101)); - events.push_back(CreateScreenBrightnessChangedEvent(123, bucketStartTimeNs + 201)); - events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + 203)); - events.push_back( - CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 99)); - events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs - 2)); - events.push_back(CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + bucketSizeNs - 1)); - events.push_back(CreateScreenBrightnessChangedEvent(456, bucketStartTimeNs + bucketSizeNs + 2)); - events.push_back( - CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 11)); - events.push_back( - CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 9)); - events.push_back( - CreateScreenBrightnessChangedEvent(789, bucketStartTimeNs + 2 * bucketSizeNs - 1)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, - ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::CountMetricDataWrapper countMetrics; - sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics); - - EXPECT_EQ(countMetrics.data_size(), 7); - auto data = countMetrics.data(0); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 123); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - - data = countMetrics.data(1); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 123); - ValidateAttributionUidDimension(data.dimensions_in_condition(), - android::util::WAKELOCK_STATE_CHANGED, 111); - - data = countMetrics.data(2); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 3); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456); - ValidateAttributionUidDimension(data.dimensions_in_condition(), - android::util::WAKELOCK_STATE_CHANGED, 111); - - data = countMetrics.data(3); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).count(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).count(), 1); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 456); - ValidateAttributionUidDimension(data.dimensions_in_condition(), - android::util::WAKELOCK_STATE_CHANGED, 333); - - data = countMetrics.data(4); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - - data = countMetrics.data(5); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789); - ValidateAttributionUidDimension(data.dimensions_in_condition(), - android::util::WAKELOCK_STATE_CHANGED, 111); - - data = countMetrics.data(6); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::SCREEN_BRIGHTNESS_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 789); - ValidateAttributionUidDimension(data.dimensions_in_condition(), - android::util::WAKELOCK_STATE_CHANGED, 333); -} - -namespace { - -StatsdConfig CreateCountMetric_Link_CombinationCondition() { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - auto appCrashMatcher = CreateProcessCrashAtomMatcher(); - *config.add_atom_matcher() = appCrashMatcher; - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED, - {Position::FIRST}); - syncDimension->add_child()->set_field(2 /* name field*/); - - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(987654); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_count_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("AppCrashMetric")); - metric->set_what(appCrashMatcher.id()); - metric->set_condition(combinationPredicate->id()); - *metric->mutable_dimensions_in_what() = - CreateDimensions(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1 /* uid */}); - *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - - // Links between crash atom and condition of app is in syncing. - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - auto dimensionWhat = links->mutable_fields_in_what(); - dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - dimensionWhat->add_child()->set_field(1); // uid field. - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition) { - ConfigKey cfgKey; - auto config = CreateCountMetric_Link_CombinationCondition(); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"), - CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"), - CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 11)); - events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 101)); - events.push_back(CreateAppCrashEvent(222, bucketStartTimeNs + 101)); - - events.push_back(CreateAppCrashEvent(222, bucketStartTimeNs + 201)); - events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 211)); - events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + 211)); - - events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + 401)); - events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + 401)); - events.push_back(CreateAppCrashEvent(555, bucketStartTimeNs + 401)); - - events.push_back(CreateAppCrashEvent(111, bucketStartTimeNs + bucketSizeNs + 301)); - events.push_back(CreateAppCrashEvent(333, bucketStartTimeNs + bucketSizeNs + 301)); - - events.push_back(CreateAppCrashEvent(777, bucketStartTimeNs + bucketSizeNs + 701)); - - events.push_back( - CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 100)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 202)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + bucketSizeNs + 700)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200)); - events.push_back( - CreateSyncEndEvent(attributions1, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400)); - events.push_back( - CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 400)); - events.push_back( - CreateSyncEndEvent(attributions2, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 600)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, - ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::CountMetricDataWrapper countMetrics; - sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics); - - EXPECT_EQ(countMetrics.data_size(), 5); - auto data = countMetrics.data(0); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - - data = countMetrics.data(1); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - - data = countMetrics.data(2); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 222); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - - data = countMetrics.data(3); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).count(), 1); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); - - data = countMetrics.data(4); - EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 777); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).count(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); -} - -namespace { - -StatsdConfig CreateDurationMetricConfig_NoLink_CombinationCondition( - DurationMetric::AggregationType aggregationType) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher(); - *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto inBatterySaverModePredicate = CreateBatterySaverModePredicate(); - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED, - {Position::FIRST}); - syncDimension->add_child()->set_field(2 /* name field */); - - *config.add_predicate() = inBatterySaverModePredicate; - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(987654); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("BatterySaverModeDurationMetric")); - metric->set_what(inBatterySaverModePredicate.id()); - metric->set_condition(combinationPredicate->id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition) { - for (auto aggregationType : { DurationMetric::MAX_SPARSE, DurationMetric::SUM}) { - ConfigKey cfgKey; - auto config = CreateDurationMetricConfig_NoLink_CombinationCondition(aggregationType); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 1)); - events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 101)); - events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 110)); - - events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 201)); - events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 500)); - - events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 600)); - events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + bucketSizeNs + 870)); - events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 10)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 100)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 202)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + bucketSizeNs + 800)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 300)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400)); - events.push_back( - CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, - ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metrics); - - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - EXPECT_FALSE(data.dimensions_in_what().has_field()); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 30); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 30); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - - data = metrics.data(1); - EXPECT_FALSE(data.dimensions_in_what().has_field()); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 2); - - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 300); - } else { - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 300); - } - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - EXPECT_FALSE(data.dimensions_in_what().has_field()); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - } else { - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs + 700 - 600); - } - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } -} - -namespace { - -StatsdConfig CreateDurationMetricConfig_Link_CombinationCondition( - DurationMetric::AggregationType aggregationType) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher(); - *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto screenIsOffPredicate = CreateScreenIsOffPredicate(); - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED, - {Position::FIRST}); - syncDimension->add_child()->set_field(2 /* name field */); - - auto isInBackgroundPredicate = CreateIsInBackgroundPredicate(); - *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() = - CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */}); - - *config.add_predicate() = screenIsOffPredicate; - *config.add_predicate() = isSyncingPredicate; - *config.add_predicate() = isInBackgroundPredicate; - auto combinationPredicate = config.add_predicate(); - combinationPredicate->set_id(987654); - combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR); - addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate); - addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate); - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("AppInBackgroundMetric")); - metric->set_what(isInBackgroundPredicate.id()); - metric->set_condition(combinationPredicate->id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_what() = - CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */}); - *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - - // Links between crash atom and condition of app is in syncing. - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - auto dimensionWhat = links->mutable_fields_in_what(); - dimensionWhat->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED); - dimensionWhat->add_child()->set_field(1); // uid field. - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = CreateDurationMetricConfig_Link_CombinationCondition(aggregationType); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateMoveToBackgroundEvent(111, bucketStartTimeNs + 101)); - events.push_back(CreateMoveToForegroundEvent(111, bucketStartTimeNs + 110)); - - events.push_back(CreateMoveToBackgroundEvent(111, bucketStartTimeNs + 201)); - events.push_back(CreateMoveToForegroundEvent(111, bucketStartTimeNs + bucketSizeNs + 100)); - - events.push_back(CreateMoveToBackgroundEvent(333, bucketStartTimeNs + 399)); - events.push_back(CreateMoveToForegroundEvent(333, bucketStartTimeNs + bucketSizeNs + 800)); - - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 10)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + 100)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, - bucketStartTimeNs + 202)); - events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, - bucketStartTimeNs + bucketSizeNs + 801)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", bucketStartTimeNs + 200)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 300)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", bucketStartTimeNs + 400)); - events.push_back( - CreateSyncEndEvent(attributions1, "ReadDoc", bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", bucketStartTimeNs + 401)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, - ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metrics); - - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111); - EXPECT_FALSE(data.dimensions_in_condition().has_field()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 9); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 111); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 201); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs + 100 - 201); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - - data = metrics.data(2); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 333); - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 401); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs + 299); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } -} - -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp deleted file mode 100644 index 489bb0b21a2e..000000000000 --- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp +++ /dev/null @@ -1,814 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <gtest/gtest.h> - -#include "src/StatsLogProcessor.h" -#include "src/stats_log_util.h" -#include "tests/statsd_test_util.h" - -#include <vector> - -namespace android { -namespace os { -namespace statsd { - -#ifdef __ANDROID__ - -namespace { - -StatsdConfig CreateDurationMetricConfig_NoLink_SimpleCondition( - DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED); - dimensions->add_child()->set_field(2); // job name field. - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED, - {Position::FIRST}); - if (addExtraDimensionInCondition) { - syncDimension->add_child()->set_field(2 /* name field*/); - } - - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = isSyncingPredicate; - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(isSyncingPredicate.id()); - metric->set_aggregation_type(aggregationType); - auto dimensionWhat = metric->mutable_dimensions_in_what(); - dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED); - dimensionWhat->add_child()->set_field(2); // job name field. - *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition) { - for (bool isDimensionInConditionSubSetOfConditionTrackerDimension : {true, false}) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = CreateDurationMetricConfig_NoLink_SimpleCondition( - aggregationType, isDimensionInConditionSubSetOfConditionTrackerDimension); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(9999, "")}, "job0", bucketStartTimeNs + 1)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(9999, "")}, "job0",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(9999, "")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(9999, "")}, "job2",bucketStartTimeNs + 500)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(8888, "")}, "job2", bucketStartTimeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(8888, "")}, "job2",bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 10)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 200)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 300)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 401)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, - true, ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job0"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job1"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 300); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job0"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 40); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job1"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 111, "App1"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 201); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 300); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - EXPECT_EQ(data.dimensions_in_what().field(), - android::util::SCHEDULED_JOB_STATE_CHANGED); - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), - 2); // job name field - EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str(), - "job2"); // job name - ValidateAttributionUidAndTagDimension(data.dimensions_in_condition(), - android::util::SYNC_STATE_CHANGED, 333, "App2"); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 401 ); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } - } -} - -namespace { - -StatsdConfig createDurationMetric_Link_SimpleConditionConfig( - DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - *dimensions = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - dimensions->add_child()->set_field(2); // job name field. - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - if (addExtraDimensionInCondition) { - syncDimension->add_child()->set_field(2 /* name field*/); - } - - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = isSyncingPredicate; - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(isSyncingPredicate.id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - *links->mutable_fields_in_what() = - CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition) { - for (bool isFullLink : {true, false}) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = createDurationMetric_Link_SimpleConditionConfig( - aggregationType, !isFullLink); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions3 = { - CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500)); - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600)); - events.push_back( - CreateFinishScheduledJobEvent({CreateAttribution(333, "App2")}, "job2", - bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back( - CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs - 2)); - events.push_back( - CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 110)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 300)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 550)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 800)); - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, - true, ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 3); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 701); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } - } -} - -namespace { - -StatsdConfig createDurationMetric_PartialLink_SimpleConditionConfig( - DurationMetric::AggregationType aggregationType) { - StatsdConfig config; - config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. - *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher(); - *config.add_atom_matcher() = CreateSyncStartAtomMatcher(); - *config.add_atom_matcher() = CreateSyncEndAtomMatcher(); - - auto scheduledJobPredicate = CreateScheduledJobPredicate(); - auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions(); - *dimensions = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - dimensions->add_child()->set_field(2); // job name field. - - auto isSyncingPredicate = CreateIsSyncingPredicate(); - auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions(); - *syncDimension = CreateAttributionUidDimensions( - android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - syncDimension->add_child()->set_field(2 /* name field*/); - - *config.add_predicate() = scheduledJobPredicate; - *config.add_predicate() = isSyncingPredicate; - - auto metric = config.add_duration_metric(); - metric->set_bucket(FIVE_MINUTES); - metric->set_id(StringToId("scheduledJob")); - metric->set_what(scheduledJobPredicate.id()); - metric->set_condition(isSyncingPredicate.id()); - metric->set_aggregation_type(aggregationType); - *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *metric->mutable_dimensions_in_condition() = *syncDimension; - - auto links = metric->add_links(); - links->set_condition(isSyncingPredicate.id()); - *links->mutable_fields_in_what() = - CreateAttributionUidDimensions( - android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST}); - *links->mutable_fields_in_condition() = - CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST}); - return config; -} - -} // namespace - -TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition) { - for (auto aggregationType : {DurationMetric::SUM, DurationMetric::MAX_SPARSE}) { - ConfigKey cfgKey; - auto config = createDurationMetric_PartialLink_SimpleConditionConfig( - aggregationType); - int64_t bucketStartTimeNs = 10000000000; - int64_t bucketSizeNs = - TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL; - - auto processor = CreateStatsLogProcessor( - bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); - EXPECT_EQ(processor->mMetricsManagers.size(), 1u); - EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - - std::vector<AttributionNodeInternal> attributions1 = { - CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(222, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions2 = { - CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<AttributionNodeInternal> attributions3 = { - CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"), - CreateAttribution(555, "GMSCoreModule2")}; - - std::vector<std::unique_ptr<LogEvent>> events; - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101)); - - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500)); - events.push_back(CreateStartScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600)); - events.push_back(CreateFinishScheduledJobEvent( - {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + bucketSizeNs + 850)); - - events.push_back( - CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs - 2)); - events.push_back( - CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3", - bucketStartTimeNs + bucketSizeNs + 900)); - - events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 50)); - events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail", - bucketStartTimeNs + 110)); - - events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail", - bucketStartTimeNs + 300)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail", - bucketStartTimeNs + bucketSizeNs + 700)); - events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc", - bucketStartTimeNs + 400)); - events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 550)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + 800)); - events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs - 1)); - events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc", - bucketStartTimeNs + bucketSizeNs + 700)); - - sortLogEventsByTimestamp(&events); - - for (const auto& event : events) { - processor->OnLogEvent(event.get()); - } - - ConfigMetricsReportList reports; - vector<uint8_t> buffer; - processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, - ADB_DUMP, FAST, &buffer); - EXPECT_TRUE(buffer.size() > 0); - EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); - backfillDimensionPath(&reports); - backfillStringInReport(&reports); - backfillStartEndTimestamp(&reports); - - EXPECT_EQ(reports.reports_size(), 1); - EXPECT_EQ(reports.reports(0).metrics_size(), 1); - StatsLogReport::DurationMetricDataWrapper metrics; - sortMetricDataByDimensionsValue( - reports.reports(0).metrics(0).duration_metrics(), &metrics); - - if (aggregationType == DurationMetric::SUM) { - EXPECT_EQ(4, metrics.data_size()); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), bucketSizeNs - 1 - 400 - 100); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300 + bucketSizeNs - 600); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 1); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } else { - EXPECT_EQ(metrics.data_size(), 4); - auto data = metrics.data(0); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 111); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 111); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 101 - 50); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - - data = metrics.data(1); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 100); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 1 - 600); - - data = metrics.data(2); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 333); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 333); - EXPECT_EQ("ReadEmail", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 2); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 500 - 300); - EXPECT_EQ(data.bucket_info(1).duration_nanos(), bucketSizeNs - 600 + 700); - EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - - data = metrics.data(3); - ValidateAttributionUidDimension( - data.dimensions_in_what(), android::util::SCHEDULED_JOB_STATE_CHANGED, 444); - ValidateAttributionUidDimension( - data.dimensions_in_condition(), android::util::SYNC_STATE_CHANGED, 444); - EXPECT_EQ("ReadDoc", - data.dimensions_in_condition().value_tuple().dimensions_value(1).value_str()); - EXPECT_EQ(data.bucket_info_size(), 1); - EXPECT_EQ(data.bucket_info(0).duration_nanos(), 701); - EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), - bucketStartTimeNs + bucketSizeNs); - EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), - bucketStartTimeNs + 2 * bucketSizeNs); - } - } -} - -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp index 67c704eb87fd..839daa4b7f8a 100644 --- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp @@ -187,9 +187,9 @@ TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) { {getMockedDimensionKey(conditionTagId, 2, "222")}; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse)); + EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse)); - EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue)); + EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue)); CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard, bucketStartTimeNs, bucketStartTimeNs); diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp index d2fd95c818cf..f30873b92afc 100644 --- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp @@ -113,9 +113,9 @@ TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) { key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {getMockedDimensionKey(conditionTagId, 2, "222")}; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse)); + EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse)); - EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue)); + EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue)); EventMetricProducer eventProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs); diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index b9553a8fded8..47c21aa8f1df 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -485,10 +485,6 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { dim->set_field(tagId); dim->add_child()->set_field(1); - dim = metric.mutable_dimensions_in_condition(); - dim->set_field(conditionTag); - dim->add_child()->set_field(1); - UidMap uidMap; SimpleAtomMatcher atomMatcher; atomMatcher.set_atom_id(tagId); @@ -496,18 +492,14 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - EXPECT_CALL(*wizard, query(_, _, _, _, _, _)) + EXPECT_CALL(*wizard, query(_, _, _)) .WillRepeatedly( Invoke([](const int conditionIndex, const ConditionKey& conditionParameters, - const vector<Matcher>& dimensionFields, const bool isSubsetDim, - const bool isPartialLink, - std::unordered_set<HashableDimensionKey>* dimensionKeySet) { - dimensionKeySet->clear(); + const bool isPartialLink) { int pos[] = {1, 0, 0}; Field f(conditionTag, pos, 0); HashableDimensionKey key; key.mutableValues()->emplace_back(f, Value((int32_t)1000000)); - dimensionKeySet->insert(key); return ConditionState::kTrue; })); @@ -538,9 +530,6 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size()); EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value); - EXPECT_EQ(1UL, key.getDimensionKeyInCondition().getValues().size()); - EXPECT_EQ(1000000, key.getDimensionKeyInCondition().getValues()[0].mValue.int_value); - EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size()); vector<shared_ptr<LogEvent>> allData; diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp index bf047520cc77..100220b730d7 100644 --- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp +++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp @@ -52,7 +52,6 @@ TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) { const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1"); const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); @@ -63,7 +62,7 @@ TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) { int64_t bucketNum = 0; int64_t metricId = 1; - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -88,7 +87,6 @@ TEST(MaxDurationTrackerTest, TestStopAll) { const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1"); const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -99,7 +97,7 @@ TEST(MaxDurationTrackerTest, TestStopAll) { int64_t bucketNum = 0; int64_t metricId = 1; - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -124,7 +122,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) { const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1"); const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1"); const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -135,7 +132,7 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) { int64_t bucketNum = 0; int64_t metricId = 1; - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -165,7 +162,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) { const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1"); const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1"); const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -176,7 +172,7 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) { int64_t bucketNum = 0; int64_t metricId = 1; - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -202,7 +198,6 @@ TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) { TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) { const HashableDimensionKey conditionDimKey = key1; - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey conditionKey1; @@ -223,7 +218,7 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) { int64_t eventStopTimeNs = conditionStops2 + 8 * NS_PER_SEC; int64_t metricId = 1; - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, true, false, {}); EXPECT_TRUE(tracker.mAnomalyTrackers.empty()); @@ -246,7 +241,6 @@ TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) { } TEST(MaxDurationTrackerTest, TestAnomalyDetection) { - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey conditionKey1; @@ -273,7 +267,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -295,7 +289,6 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) { // This tests that we correctly compute the predicted time of an anomaly assuming that the current // state continues forward as-is. TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) { - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey conditionKey1; @@ -333,7 +326,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -381,7 +374,6 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) { // Suppose A starts, then B starts, and then A stops. We still need to set an anomaly based on the // elapsed duration of B. TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) { - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey conditionKey1; @@ -416,7 +408,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -434,4 +426,4 @@ TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) { } // namespace android #else GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif
\ No newline at end of file +#endif diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp index 7c2b4236add8..1cd7bdbf7bb0 100644 --- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp +++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp @@ -51,7 +51,6 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -62,7 +61,7 @@ TEST(OringDurationTrackerTest, TestDurationOverlap) { int64_t eventStartTimeNs = bucketStartTimeNs + 1; int64_t durationTimeNs = 2 * 1000; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -84,7 +83,6 @@ TEST(OringDurationTrackerTest, TestDurationNested) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -94,7 +92,7 @@ TEST(OringDurationTrackerTest, TestDurationNested) { int64_t bucketNum = 0; int64_t eventStartTimeNs = bucketStartTimeNs + 1; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -117,7 +115,6 @@ TEST(OringDurationTrackerTest, TestStopAll) { {getMockedDimensionKey(TagId, 1, "maps")}; const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -127,7 +124,7 @@ TEST(OringDurationTrackerTest, TestStopAll) { int64_t bucketNum = 0; int64_t eventStartTimeNs = bucketStartTimeNs + 1; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -147,7 +144,6 @@ TEST(OringDurationTrackerTest, TestCrossBucketBoundary) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -158,7 +154,7 @@ TEST(OringDurationTrackerTest, TestCrossBucketBoundary) { int64_t eventStartTimeNs = bucketStartTimeNs + 1; int64_t durationTimeNs = 2 * 1000; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {}); @@ -186,13 +182,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey key1; key1[StringToId("APP_BACKGROUND")] = kConditionKey1; - EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)) // #4 + EXPECT_CALL(*wizard, query(_, key1, _)) // #4 .WillOnce(Return(ConditionState::kFalse)); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -203,7 +198,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) { int64_t eventStartTimeNs = bucketStartTimeNs + 1; int64_t durationTimeNs = 2 * 1000; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {}); @@ -224,13 +219,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey key1; key1[StringToId("APP_BACKGROUND")] = kConditionKey1; - EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)) + EXPECT_CALL(*wizard, query(_, key1, _)) .Times(2) .WillOnce(Return(ConditionState::kFalse)) .WillOnce(Return(ConditionState::kTrue)); @@ -243,7 +237,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) { int64_t eventStartTimeNs = bucketStartTimeNs + 1; int64_t durationTimeNs = 2 * 1000; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {}); @@ -266,13 +260,12 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); ConditionKey key1; key1[StringToId("APP_BACKGROUND")] = kConditionKey1; - EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)) // #4 + EXPECT_CALL(*wizard, query(_, key1, _)) // #4 .WillOnce(Return(ConditionState::kFalse)); unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets; @@ -282,7 +275,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) { int64_t bucketNum = 0; int64_t eventStartTimeNs = bucketStartTimeNs + 1; - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {}); @@ -306,7 +299,6 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; Alert alert; alert.set_id(101); alert.set_metric_id(1); @@ -324,7 +316,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -371,7 +363,6 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) { } TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) { - vector<Matcher> dimensionInCondition; Alert alert; alert.set_id(101); alert.set_metric_id(1); @@ -387,7 +378,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) { sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard, 1, - dimensionInCondition, + true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -415,7 +406,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) { for (int j = 0; j < 3; j++) { int64_t thresholdNs = j * bucketSizeNs + 5 * NS_PER_SEC; for (int i = 0; i <= 7; ++i) { - vector<Matcher> dimensionInCondition; + Alert alert; alert.set_id(101); alert.set_metric_id(1); @@ -432,7 +423,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) { sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, - wizard, 1, dimensionInCondition, + wizard, 1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {anomalyTracker}); @@ -472,7 +463,6 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; Alert alert; alert.set_id(101); alert.set_metric_id(1); @@ -491,7 +481,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {anomalyTracker}); @@ -522,7 +512,6 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) { const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps"); const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps"); - vector<Matcher> dimensionInCondition; Alert alert; alert.set_id(101); alert.set_metric_id(1); @@ -541,7 +530,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) { sp<AlarmMonitor> alarmMonitor; sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor); - OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition, + OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/, bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, false, false, {anomalyTracker}); @@ -589,4 +578,4 @@ TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) { } // namespace android #else GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif
\ No newline at end of file +#endif diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h index 97c107228f9c..329e39fc4eff 100644 --- a/cmds/statsd/tests/metrics/metrics_test_helper.h +++ b/cmds/statsd/tests/metrics/metrics_test_helper.h @@ -26,11 +26,9 @@ namespace statsd { class MockConditionWizard : public ConditionWizard { public: - MOCK_METHOD6(query, + MOCK_METHOD3(query, ConditionState(const int conditionIndex, const ConditionKey& conditionParameters, - const vector<Matcher>& dimensionFields, - const bool isSubsetDim, const bool isPartialLink, - std::unordered_set<HashableDimensionKey>* dimensionKeySet)); + const bool isPartialLink)); }; class MockStatsPullerManager : public StatsPullerManager { @@ -55,4 +53,4 @@ void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher); } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android |