diff options
25 files changed, 1627 insertions, 857 deletions
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 1579715727ac..7c419519a558 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -85,8 +85,9 @@ cc_defaults { "src/metrics/EventMetricProducer.cpp", "src/metrics/GaugeMetricProducer.cpp", "src/metrics/MetricProducer.cpp", - "src/metrics/metrics_manager_util.cpp", "src/metrics/MetricsManager.cpp", + "src/metrics/parsing_utils/config_update_utils.cpp", + "src/metrics/parsing_utils/metrics_manager_util.cpp", "src/metrics/ValueMetricProducer.cpp", "src/packages/UidMap.cpp", "src/shell/shell_config.proto", @@ -322,6 +323,8 @@ cc_test { "tests/metrics/metrics_test_helper.cpp", "tests/metrics/OringDurationTracker_test.cpp", "tests/metrics/ValueMetricProducer_test.cpp", + "tests/metrics/parsing_utils/config_update_utils_test.cpp", + "tests/metrics/parsing_utils/metrics_manager_util_test.cpp", "tests/MetricsManager_test.cpp", "tests/shell/ShellSubscriber_test.cpp", "tests/state/StateTracker_test.cpp", diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 6327490b0b71..7bee4e2d1a36 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -546,7 +546,8 @@ void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const C } } else { // Preserve the existing MetricsManager, update necessary components and metadata in place. - configValid = it->second->updateConfig(timestampNs, config); + configValid = it->second->updateConfig(config, mTimeBaseNs, timestampNs, + mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); if (configValid) { // TODO(b/162323476): refresh TTL, ensure init() is handled properly. mUidMap->OnConfigUpdated(key); diff --git a/cmds/statsd/src/hash.h b/cmds/statsd/src/hash.h index cfe869f60202..bd6b0cd47eaf 100644 --- a/cmds/statsd/src/hash.h +++ b/cmds/statsd/src/hash.h @@ -22,6 +22,7 @@ namespace android { namespace os { namespace statsd { +// Uses murmur2 hashing algorithm. extern uint32_t Hash32(const char *data, size_t n, uint32_t seed); extern uint64_t Hash64(const char* data, size_t n, uint64_t seed); diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp index b94a9572113e..60bcc26f0873 100644 --- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp @@ -27,8 +27,9 @@ using std::set; using std::unordered_map; using std::vector; -CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index) - : LogMatchingTracker(id, index) { +CombinationLogMatchingTracker::CombinationLogMatchingTracker(const int64_t& id, const int index, + const uint64_t protoHash) + : LogMatchingTracker(id, index, protoHash) { } CombinationLogMatchingTracker::~CombinationLogMatchingTracker() { diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h index 55bc46059fc1..6b8a7fb19cf0 100644 --- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h +++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.h @@ -28,7 +28,7 @@ namespace statsd { // Represents a AtomMatcher_Combination in the StatsdConfig. class CombinationLogMatchingTracker : public virtual LogMatchingTracker { public: - CombinationLogMatchingTracker(const int64_t& id, const int index); + CombinationLogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash); bool init(const std::vector<AtomMatcher>& allLogMatchers, const std::vector<sp<LogMatchingTracker>>& allTrackers, diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h index 88ab4e6f683a..49a41add4560 100644 --- a/cmds/statsd/src/matchers/LogMatchingTracker.h +++ b/cmds/statsd/src/matchers/LogMatchingTracker.h @@ -33,8 +33,8 @@ namespace statsd { class LogMatchingTracker : public virtual RefBase { public: - LogMatchingTracker(const int64_t& id, const int index) - : mId(id), mIndex(index), mInitialized(false){}; + LogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash) + : mId(id), mIndex(index), mInitialized(false), mProtoHash(protoHash){}; virtual ~LogMatchingTracker(){}; @@ -69,10 +69,14 @@ public: return mAtomIds; } - const int64_t& getId() const { + int64_t getId() const { return mId; } + uint64_t getProtoHash() const { + return mProtoHash; + } + protected: // Name of this matching. We don't really need the name, but it makes log message easy to debug. const int64_t mId; @@ -87,6 +91,14 @@ protected: // return kNotMatched when we receive an event with an id not in the list. This is especially // useful when we have a complex CombinationLogMatcherTracker. std::set<int> mAtomIds; + + // Hash of the AtomMatcher's proto bytes from StatsdConfig. + // Used to determine if the definition of this matcher has changed across a config update. + const uint64_t mProtoHash; + + FRIEND_TEST(MetricsManagerTest, TestCreateLogTrackerSimple); + FRIEND_TEST(MetricsManagerTest, TestCreateLogTrackerCombination); + FRIEND_TEST(ConfigUpdateTest, TestUpdateMatchers); }; } // namespace statsd diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp index 082daf5a1916..ff47d35b36cc 100644 --- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp @@ -26,11 +26,11 @@ namespace statsd { using std::unordered_map; using std::vector; - SimpleLogMatchingTracker::SimpleLogMatchingTracker(const int64_t& id, const int index, + const uint64_t protoHash, const SimpleAtomMatcher& matcher, - const UidMap& uidMap) - : LogMatchingTracker(id, index), mMatcher(matcher), mUidMap(uidMap) { + const sp<UidMap>& uidMap) + : LogMatchingTracker(id, index, protoHash), mMatcher(matcher), mUidMap(uidMap) { if (!matcher.has_atom_id()) { mInitialized = false; } else { diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h index a0f6a888bd44..e58e01252ade 100644 --- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h +++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.h @@ -29,9 +29,8 @@ namespace statsd { class SimpleLogMatchingTracker : public virtual LogMatchingTracker { public: - SimpleLogMatchingTracker(const int64_t& id, const int index, - const SimpleAtomMatcher& matcher, - const UidMap& uidMap); + SimpleLogMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash, + const SimpleAtomMatcher& matcher, const sp<UidMap>& uidMap); ~SimpleLogMatchingTracker(); @@ -46,7 +45,7 @@ public: private: const SimpleAtomMatcher mMatcher; - const UidMap& mUidMap; + const sp<UidMap> mUidMap; }; } // namespace statsd diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp index 2b4c6a3cbf1e..e6d91223308d 100644 --- a/cmds/statsd/src/matchers/matcher_util.cpp +++ b/cmds/statsd/src/matchers/matcher_util.cpp @@ -81,14 +81,15 @@ bool combinationMatch(const vector<int>& children, const LogicalOperation& opera return matched; } -bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) { +bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue, + const string& str_match) { if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) { int uid = fieldValue.mValue.int_value; auto aidIt = UidMap::sAidToUidMapping.find(str_match); if (aidIt != UidMap::sAidToUidMapping.end()) { return ((int)aidIt->second) == uid; } - std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/); + std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/); return packageNames.find(str_match) != packageNames.end(); } else if (fieldValue.mValue.getType() == STRING) { return fieldValue.mValue.str_value == str_match; @@ -96,7 +97,7 @@ bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const st return false; } -bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, +bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher, const vector<FieldValue>& values, int start, int end, int depth) { if (depth > 2) { ALOGE("Depth > 3 not supported"); @@ -353,7 +354,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } -bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher, +bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher, const LogEvent& event) { if (event.GetTagId() != simpleMatcher.atom_id()) { return false; diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h index 1ab3e87b5fed..130b6068bd19 100644 --- a/cmds/statsd/src/matchers/matcher_util.h +++ b/cmds/statsd/src/matchers/matcher_util.h @@ -36,8 +36,8 @@ enum MatchingState { bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation, const std::vector<MatchingState>& matcherResults); -bool matchesSimple(const UidMap& uidMap, - const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper); +bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher, + const LogEvent& wrapper); } // namespace statsd } // namespace os diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 189d8117ae55..2c3deca40fa0 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -26,7 +26,8 @@ #include "guardrail/StatsdStats.h" #include "matchers/CombinationLogMatchingTracker.h" #include "matchers/SimpleLogMatchingTracker.h" -#include "metrics_manager_util.h" +#include "parsing_utils/config_update_utils.h" +#include "parsing_utils/metrics_manager_util.h" #include "state/StateManager.h" #include "stats_log_util.h" #include "stats_util.h" @@ -76,13 +77,14 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config, // Init the ttl end timestamp. refreshTtl(timeBaseNs); - mConfigValid = initStatsdConfig( - key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers, - mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers, - mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap, - mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap, - mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds); + mConfigValid = + initStatsdConfig(key, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseNs, currentTimeNs, mTagIds, + mAllAtomMatchers, mLogTrackerMap, mAllConditionTrackers, + mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers, + mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap, + mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap, + mAlertTrackerMap, mMetricIndexesWithActivation, mNoReportMetricIds); mHashStringsInReport = config.hash_strings_in_metric_report(); mVersionStringsInReport = config.version_strings_in_metric_report(); @@ -195,7 +197,19 @@ MetricsManager::~MetricsManager() { VLOG("~MetricsManager()"); } -bool MetricsManager::updateConfig(const int64_t currentTimeNs, const StatsdConfig& config) { +bool MetricsManager::updateConfig(const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, + const sp<AlarmMonitor>& anomalyAlarmMonitor, + const sp<AlarmMonitor>& periodicAlarmMonitor) { + vector<sp<LogMatchingTracker>> newAtomMatchers; + unordered_map<int64_t, int> newLogTrackerMap; + mTagIds.clear(); + mConfigValid = + updateStatsdConfig(mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseNs, currentTimeNs, mAllAtomMatchers, + mLogTrackerMap, mTagIds, newAtomMatchers, newLogTrackerMap); + mAllAtomMatchers = newAtomMatchers; + mLogTrackerMap = newLogTrackerMap; return mConfigValid; } diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 042de29e173d..6f9a23362033 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -46,7 +46,9 @@ public: virtual ~MetricsManager(); - bool updateConfig(const int64_t currentTimeNs, const StatsdConfig& config); + bool updateConfig(const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const sp<AlarmMonitor>& anomalyAlarmMonitor, + const sp<AlarmMonitor>& periodicAlarmMonitor); // Return whether the configuration is valid. bool isConfigValid() const; @@ -237,6 +239,12 @@ private: // Hold all periodic alarm trackers. std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers; + // To make updating configs faster, we map the id of a LogMatchingTracker, MetricProducer, and + // ConditionTracker to its index in the corresponding vector. + + // Maps the id of an atom matcher to its index in mAllAtomMatchers. + std::unordered_map<int64_t, int> mLogTrackerMap; + // To make the log processing more efficient, we want to do as much filtering as possible // before we go into individual trackers and conditions to match. diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp new file mode 100644 index 000000000000..562e29124187 --- /dev/null +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2020 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. + */ + +#define DEBUG false // STOPSHIP if true + +#include "config_update_utils.h" + +#include "external/StatsPullerManager.h" +#include "hash.h" +#include "metrics_manager_util.h" + +namespace android { +namespace os { +namespace statsd { + +// Recursive function to determine if a matcher needs to be updated. Populates matcherToUpdate. +// Returns whether the function was successful or not. +bool determineMatcherUpdateStatus(const StatsdConfig& config, const int matcherIdx, + const unordered_map<int64_t, int>& oldLogTrackerMap, + const vector<sp<LogMatchingTracker>>& oldAtomMatchers, + const unordered_map<int64_t, int>& newLogTrackerMap, + vector<UpdateStatus>& matchersToUpdate, + vector<bool>& cycleTracker) { + // Have already examined this matcher. + if (matchersToUpdate[matcherIdx] != UPDATE_UNKNOWN) { + return true; + } + + const AtomMatcher& matcher = config.atom_matcher(matcherIdx); + int64_t id = matcher.id(); + // Check if new matcher. + const auto& oldLogTrackerIt = oldLogTrackerMap.find(id); + if (oldLogTrackerIt == oldLogTrackerMap.end()) { + matchersToUpdate[matcherIdx] = UPDATE_REPLACE; + return true; + } + + // This is an existing matcher. Check if it has changed. + string serializedMatcher; + if (!matcher.SerializeToString(&serializedMatcher)) { + ALOGE("Unable to serialize matcher %lld", (long long)id); + return false; + } + uint64_t newProtoHash = Hash64(serializedMatcher); + if (newProtoHash != oldAtomMatchers[oldLogTrackerIt->second]->getProtoHash()) { + matchersToUpdate[matcherIdx] = UPDATE_REPLACE; + return true; + } + + switch (matcher.contents_case()) { + case AtomMatcher::ContentsCase::kSimpleAtomMatcher: { + matchersToUpdate[matcherIdx] = UPDATE_PRESERVE; + return true; + } + case AtomMatcher::ContentsCase::kCombination: { + // Recurse to check if children have changed. + cycleTracker[matcherIdx] = true; + UpdateStatus status = UPDATE_PRESERVE; + for (const int64_t childMatcherId : matcher.combination().matcher()) { + const auto& childIt = newLogTrackerMap.find(childMatcherId); + if (childIt == newLogTrackerMap.end()) { + ALOGW("Matcher %lld not found in the config", (long long)childMatcherId); + return false; + } + const int childIdx = childIt->second; + if (cycleTracker[childIdx]) { + ALOGE("Cycle detected in matcher config"); + return false; + } + if (!determineMatcherUpdateStatus(config, childIdx, oldLogTrackerMap, + oldAtomMatchers, newLogTrackerMap, + matchersToUpdate, cycleTracker)) { + return false; + } + + if (matchersToUpdate[childIdx] == UPDATE_REPLACE) { + status = UPDATE_REPLACE; + break; + } + } + matchersToUpdate[matcherIdx] = status; + cycleTracker[matcherIdx] = false; + return true; + } + default: { + ALOGE("Matcher \"%lld\" malformed", (long long)id); + return false; + } + } + return true; +} + +bool updateLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap, + const unordered_map<int64_t, int>& oldLogTrackerMap, + const vector<sp<LogMatchingTracker>>& oldAtomMatchers, set<int>& allTagIds, + unordered_map<int64_t, int>& newLogTrackerMap, + vector<sp<LogMatchingTracker>>& newAtomMatchers) { + const int atomMatcherCount = config.atom_matcher_size(); + + vector<AtomMatcher> matcherProtos; + matcherProtos.reserve(atomMatcherCount); + newAtomMatchers.reserve(atomMatcherCount); + + // Maps matcher id to their position in the config. For fast lookup of dependencies. + for (int i = 0; i < atomMatcherCount; i++) { + const AtomMatcher& matcher = config.atom_matcher(i); + if (newLogTrackerMap.find(matcher.id()) != newLogTrackerMap.end()) { + ALOGE("Duplicate atom matcher found for id %lld", (long long)matcher.id()); + return false; + } + newLogTrackerMap[matcher.id()] = i; + matcherProtos.push_back(matcher); + } + + // For combination matchers, we need to determine if any children need to be updated. + vector<UpdateStatus> matchersToUpdate(atomMatcherCount, UPDATE_UNKNOWN); + vector<bool> cycleTracker(atomMatcherCount, false); + for (int i = 0; i < atomMatcherCount; i++) { + if (!determineMatcherUpdateStatus(config, i, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)) { + return false; + } + } + + for (int i = 0; i < atomMatcherCount; i++) { + const AtomMatcher& matcher = config.atom_matcher(i); + const int64_t id = matcher.id(); + switch (matchersToUpdate[i]) { + case UPDATE_PRESERVE: { + const auto& oldLogTrackerIt = oldLogTrackerMap.find(id); + if (oldLogTrackerIt == oldLogTrackerMap.end()) { + ALOGE("Could not find AtomMatcher %lld in the previous config, but expected it " + "to be there", + (long long)id); + return false; + } + const int oldIndex = oldLogTrackerIt->second; + newAtomMatchers.push_back(oldAtomMatchers[oldIndex]); + break; + } + case UPDATE_REPLACE: { + sp<LogMatchingTracker> tracker = createLogTracker(matcher, i, uidMap); + if (tracker == nullptr) { + return false; + } + newAtomMatchers.push_back(tracker); + break; + } + default: { + ALOGE("Matcher \"%lld\" update state is unknown. This should never happen", + (long long)id); + return false; + } + } + } + + std::fill(cycleTracker.begin(), cycleTracker.end(), false); + for (auto& matcher : newAtomMatchers) { + if (!matcher->init(matcherProtos, newAtomMatchers, newLogTrackerMap, cycleTracker)) { + return false; + } + // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only. + const set<int>& tagIds = matcher->getAtomIds(); + allTagIds.insert(tagIds.begin(), tagIds.end()); + } + + return true; +} + +bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap, + const sp<StatsPullerManager>& pullerManager, + const sp<AlarmMonitor>& anomalyAlarmMonitor, + const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, + const int64_t currentTimeNs, + const vector<sp<LogMatchingTracker>>& oldAtomMatchers, + const unordered_map<int64_t, int>& oldLogTrackerMap, set<int>& allTagIds, + vector<sp<LogMatchingTracker>>& newAtomMatchers, + unordered_map<int64_t, int>& newLogTrackerMap) { + if (!updateLogTrackers(config, uidMap, oldLogTrackerMap, oldAtomMatchers, allTagIds, + newLogTrackerMap, newAtomMatchers)) { + ALOGE("updateLogMatchingTrackers failed"); + return false; + } + + return true; +} + +} // namespace statsd +} // namespace os +} // namespace android
\ No newline at end of file diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h new file mode 100644 index 000000000000..951ab03cee47 --- /dev/null +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 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. + */ + +#pragma once + +#include <vector> + +#include "anomaly/AlarmMonitor.h" +#include "external/StatsPullerManager.h" +#include "matchers/LogMatchingTracker.h" + +namespace android { +namespace os { +namespace statsd { + +// Helper functions for MetricsManager to update itself from a new StatsdConfig. +// *Note*: only updateStatsdConfig() should be called from outside this file. +// All other functions are intermediate steps, created to make unit testing easier. + +// Possible update states for a component. PRESERVE means we should keep the existing one. +// REPLACE means we should create a new one, either because it didn't exist or it changed. +enum UpdateStatus { + UPDATE_UNKNOWN = 0, + UPDATE_PRESERVE = 1, + UPDATE_REPLACE = 2, +}; + +// Recursive function to determine if a matcher needs to be updated. +// input: +// [config]: the input StatsdConfig +// [matcherIdx]: the index of the current matcher to be updated +// [newLogTrackerMap]: matcher id to index mapping in the input StatsdConfig +// [oldLogTrackerMap]: matcher id to index mapping in the existing MetricsManager +// [oldAtomMatchers]: stores the existing LogMatchingTrackers +// output: +// [matchersToUpdate]: vector of the update status of each matcher. The matcherIdx index will +// be updated from UPDATE_UNKNOWN after this call. +// [cycleTracker]: intermediate param used during recursion. +bool determineMatcherUpdateStatus(const StatsdConfig& config, const int matcherIdx, + const unordered_map<int64_t, int>& oldLogTrackerMap, + const vector<sp<LogMatchingTracker>>& oldAtomMatchers, + const unordered_map<int64_t, int>& newLogTrackerMap, + vector<UpdateStatus>& matchersToUpdate, + vector<bool>& cycleTracker); + +// Updates the LogMatchingTrackers. +// input: +// [config]: the input StatsdConfig +// [oldLogTrackerMap]: existing matcher id to index mapping +// [oldAtomMatchers]: stores the existing LogMatchingTrackers +// output: +// [allTagIds]: contains the set of all interesting tag ids to this config. +// [newLogTrackerMap]: new matcher id to index mapping +// [newAtomMatchers]: stores the new LogMatchingTrackers +bool updateLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap, + const unordered_map<int64_t, int>& oldLogTrackerMap, + const vector<sp<LogMatchingTracker>>& oldAtomMatchers, set<int>& allTagIds, + unordered_map<int64_t, int>& newLogTrackerMap, + vector<sp<LogMatchingTracker>>& newAtomMatchers); + +// Updates the existing MetricsManager from a new StatsdConfig. +// Parameters are the members of MetricsManager. See MetricsManager for declaration. +bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap, + const sp<StatsPullerManager>& pullerManager, + const sp<AlarmMonitor>& anomalyAlarmMonitor, + const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, + const int64_t currentTimeNs, + const std::vector<sp<LogMatchingTracker>>& oldAtomMatchers, + const unordered_map<int64_t, int>& oldLogTrackerMap, + std::set<int>& allTagIds, + std::vector<sp<LogMatchingTracker>>& newAtomMatchers, + unordered_map<int64_t, int>& newLogTrackerMap); + +} // namespace statsd +} // namespace os +} // namespace android
\ No newline at end of file diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp index 8917c36bb608..52ef95d19cdc 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp @@ -22,10 +22,10 @@ #include <inttypes.h> #include "FieldValue.h" -#include "MetricProducer.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" #include "external/StatsPullerManager.h" +#include "hash.h" #include "matchers/CombinationLogMatchingTracker.h" #include "matchers/EventMatcherWizard.h" #include "matchers/SimpleLogMatchingTracker.h" @@ -33,6 +33,7 @@ #include "metrics/DurationMetricProducer.h" #include "metrics/EventMetricProducer.h" #include "metrics/GaugeMetricProducer.h" +#include "metrics/MetricProducer.h" #include "metrics/ValueMetricProducer.h" #include "state/StateManager.h" #include "stats_util.h" @@ -61,6 +62,28 @@ bool hasLeafNode(const FieldMatcher& matcher) { } // namespace +sp<LogMatchingTracker> createLogTracker(const AtomMatcher& logMatcher, const int index, + const sp<UidMap>& uidMap) { + string serializedMatcher; + if (!logMatcher.SerializeToString(&serializedMatcher)) { + ALOGE("Unable to serialize matcher %lld", (long long)logMatcher.id()); + return nullptr; + } + uint64_t protoHash = Hash64(serializedMatcher); + switch (logMatcher.contents_case()) { + case AtomMatcher::ContentsCase::kSimpleAtomMatcher: + return new SimpleLogMatchingTracker(logMatcher.id(), index, protoHash, + logMatcher.simple_atom_matcher(), uidMap); + break; + case AtomMatcher::ContentsCase::kCombination: + return new CombinationLogMatchingTracker(logMatcher.id(), index, protoHash); + break; + default: + ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id()); + return nullptr; + } +} + bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex, const bool usedForDimension, const vector<sp<LogMatchingTracker>>& allAtomMatchers, @@ -184,9 +207,7 @@ bool handleMetricWithStateLink(const FieldMatcher& stateMatcher, // to provide the producer with state about its activators and deactivators. // Returns false if there are errors. bool handleMetricActivation( - const StatsdConfig& config, - const int64_t metricId, - const int metricIndex, + const StatsdConfig& config, const int64_t metricId, const int metricIndex, const unordered_map<int64_t, int>& metricToActivationMap, const unordered_map<int64_t, int>& logTrackerMap, unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, @@ -210,10 +231,11 @@ bool handleMetricActivation( return false; } - ActivationType activationType = (activation.has_activation_type()) ? - activation.activation_type() : metricActivation.activation_type(); - std::shared_ptr<Activation> activationWrapper = std::make_shared<Activation>( - activationType, activation.ttl_seconds() * NS_PER_SEC); + ActivationType activationType = (activation.has_activation_type()) + ? activation.activation_type() + : metricActivation.activation_type(); + std::shared_ptr<Activation> activationWrapper = + std::make_shared<Activation>(activationType, activation.ttl_seconds() * NS_PER_SEC); int atomMatcherIndex = itr->second; activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex); @@ -235,7 +257,7 @@ bool handleMetricActivation( return true; } -bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap, +bool initLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap, unordered_map<int64_t, int>& logTrackerMap, vector<sp<LogMatchingTracker>>& allAtomMatchers, set<int>& allTagIds) { vector<AtomMatcher> matcherConfigs; @@ -245,22 +267,12 @@ bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap, for (int i = 0; i < atomMatcherCount; i++) { const AtomMatcher& logMatcher = config.atom_matcher(i); - int index = allAtomMatchers.size(); - switch (logMatcher.contents_case()) { - case AtomMatcher::ContentsCase::kSimpleAtomMatcher: - allAtomMatchers.push_back(new SimpleLogMatchingTracker( - logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap)); - break; - case AtomMatcher::ContentsCase::kCombination: - allAtomMatchers.push_back( - new CombinationLogMatchingTracker(logMatcher.id(), index)); - break; - default: - ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id()); - return false; - // continue; + sp<LogMatchingTracker> tracker = createLogTracker(logMatcher, index, uidMap); + if (tracker == nullptr) { + return false; } + allAtomMatchers.push_back(tracker); if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) { ALOGE("Duplicate AtomMatcher found!"); return false; @@ -383,7 +395,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t const MetricActivation& metricActivation = config.metric_activation(i); int64_t metricId = metricActivation.metric_id(); if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) { - ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId); + ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId); return false; } metricToActivationMap.insert({metricId, i}); @@ -402,9 +414,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t metricMap.insert({metric.id(), metricIndex}); int trackerIndex; if (!handleMetricWithLogTrackers(metric.what(), metricIndex, - metric.has_dimensions_in_what(), - allAtomMatchers, logTrackerMap, trackerToMetricMap, - trackerIndex)) { + metric.has_dimensions_in_what(), allAtomMatchers, + logTrackerMap, trackerToMetricMap, trackerIndex)) { return false; } @@ -438,10 +449,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t unordered_map<int, shared_ptr<Activation>> eventActivationMap; unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation(config, metric.id(), metricIndex, - metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap, - deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap, - eventDeactivationMap); + bool success = handleMetricActivation( + config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation, eventActivationMap, eventDeactivationMap); if (!success) return false; sp<MetricProducer> countProducer = @@ -544,10 +555,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t unordered_map<int, shared_ptr<Activation>> eventActivationMap; unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation(config, metric.id(), metricIndex, - metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap, - deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap, - eventDeactivationMap); + bool success = handleMetricActivation( + config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation, eventActivationMap, eventDeactivationMap); if (!success) return false; sp<MetricProducer> durationMetric = new DurationMetricProducer( @@ -591,10 +602,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t unordered_map<int, shared_ptr<Activation>> eventActivationMap; unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation(config, metric.id(), metricIndex, - metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap, - deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap, - eventDeactivationMap); + bool success = handleMetricActivation( + config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation, eventActivationMap, eventDeactivationMap); if (!success) return false; sp<MetricProducer> eventMetric = @@ -626,9 +637,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t metricMap.insert({metric.id(), metricIndex}); int trackerIndex; if (!handleMetricWithLogTrackers(metric.what(), metricIndex, - metric.has_dimensions_in_what(), - allAtomMatchers, logTrackerMap, trackerToMetricMap, - trackerIndex)) { + metric.has_dimensions_in_what(), allAtomMatchers, + logTrackerMap, trackerToMetricMap, trackerIndex)) { return false; } @@ -718,9 +728,8 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t metricMap.insert({metric.id(), metricIndex}); int trackerIndex; if (!handleMetricWithLogTrackers(metric.what(), metricIndex, - metric.has_dimensions_in_what(), - allAtomMatchers, logTrackerMap, trackerToMetricMap, - trackerIndex)) { + metric.has_dimensions_in_what(), allAtomMatchers, + logTrackerMap, trackerToMetricMap, trackerIndex)) { return false; } @@ -775,10 +784,10 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t unordered_map<int, shared_ptr<Activation>> eventActivationMap; unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation(config, metric.id(), metricIndex, - metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap, - deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap, - eventDeactivationMap); + bool success = handleMetricActivation( + config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation, eventActivationMap, eventDeactivationMap); if (!success) return false; sp<MetricProducer> gaugeProducer = new GaugeMetricProducer( @@ -813,8 +822,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t return true; } -bool initAlerts(const StatsdConfig& config, - const unordered_map<int64_t, int>& metricProducerMap, +bool initAlerts(const StatsdConfig& config, const unordered_map<int64_t, int>& metricProducerMap, unordered_map<int64_t, int>& alertTrackerMap, const sp<AlarmMonitor>& anomalyAlarmMonitor, vector<sp<MetricProducer>>& allMetricProducers, @@ -832,8 +840,8 @@ bool initAlerts(const StatsdConfig& config, return false; } if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) { - ALOGW("invalid alert: threshold=%f num_buckets= %d", - alert.trigger_if_sum_gt(), alert.num_buckets()); + ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(), + alert.num_buckets()); return false; } const int metricIndex = itr->second; @@ -853,14 +861,13 @@ bool initAlerts(const StatsdConfig& config, } if (subscription.subscriber_information_case() == Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) { - ALOGW("subscription \"%lld\" has no subscriber info.\"", - (long long)subscription.id()); + ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id()); return false; } const auto& itr = alertTrackerMap.find(subscription.rule_id()); if (itr == alertTrackerMap.end()) { ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"", - (long long)subscription.id(), (long long)subscription.rule_id()); + (long long)subscription.id(), (long long)subscription.rule_id()); return false; } const int anomalyTrackerIndex = itr->second; @@ -870,12 +877,11 @@ bool initAlerts(const StatsdConfig& config, } bool initAlarms(const StatsdConfig& config, const ConfigKey& key, - const sp<AlarmMonitor>& periodicAlarmMonitor, - const int64_t timeBaseNs, const int64_t currentTimeNs, - vector<sp<AlarmTracker>>& allAlarmTrackers) { + const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, + const int64_t currentTimeNs, vector<sp<AlarmTracker>>& allAlarmTrackers) { unordered_map<int64_t, int> alarmTrackerMap; int64_t startMillis = timeBaseNs / 1000 / 1000; - int64_t currentTimeMillis = currentTimeNs / 1000 /1000; + int64_t currentTimeMillis = currentTimeNs / 1000 / 1000; for (int i = 0; i < config.alarm_size(); i++) { const Alarm& alarm = config.alarm(i); if (alarm.offset_millis() <= 0) { @@ -888,8 +894,7 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key, } alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size())); allAlarmTrackers.push_back( - new AlarmTracker(startMillis, currentTimeMillis, - alarm, key, periodicAlarmMonitor)); + new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor)); } for (int i = 0; i < config.subscription_size(); ++i) { const Subscription& subscription = config.subscription(i); @@ -898,14 +903,13 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key, } if (subscription.subscriber_information_case() == Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) { - ALOGW("subscription \"%lld\" has no subscriber info.\"", - (long long)subscription.id()); + ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id()); return false; } const auto& itr = alarmTrackerMap.find(subscription.rule_id()); if (itr == alarmTrackerMap.end()) { ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"", - (long long)subscription.id(), (long long)subscription.rule_id()); + (long long)subscription.id(), (long long)subscription.rule_id()); return false; } const int trackerIndex = itr->second; @@ -914,12 +918,13 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key, return true; } -bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap, +bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, const int64_t currentTimeNs, set<int>& allTagIds, vector<sp<LogMatchingTracker>>& allAtomMatchers, + unordered_map<int64_t, int>& logTrackerMap, vector<sp<ConditionTracker>>& allConditionTrackers, vector<sp<MetricProducer>>& allMetricProducers, vector<sp<AnomalyTracker>>& allAnomalyTrackers, @@ -930,9 +935,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, unordered_map<int64_t, int>& alertTrackerMap, - vector<int>& metricsWithActivation, - std::set<int64_t>& noReportMetricIds) { - unordered_map<int64_t, int> logTrackerMap; + vector<int>& metricsWithActivation, std::set<int64_t>& noReportMetricIds) { unordered_map<int64_t, int> conditionTrackerMap; vector<ConditionState> initialConditionCache; unordered_map<int64_t, int> metricProducerMap; @@ -969,8 +972,8 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& ALOGE("initAlerts failed"); return false; } - if (!initAlarms(config, key, periodicAlarmMonitor, - timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) { + if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs, + allPeriodicAlarmTrackers)) { ALOGE("initAlarms failed"); return false; } diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h index 96b5c26ff789..ed9951fd5ee6 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h @@ -20,16 +20,28 @@ #include <unordered_map> #include <vector> -#include "../anomaly/AlarmTracker.h" -#include "../condition/ConditionTracker.h" -#include "../external/StatsPullerManager.h" -#include "../matchers/LogMatchingTracker.h" -#include "../metrics/MetricProducer.h" +#include "anomaly/AlarmTracker.h" +#include "condition/ConditionTracker.h" +#include "external/StatsPullerManager.h" +#include "matchers/LogMatchingTracker.h" +#include "metrics/MetricProducer.h" namespace android { namespace os { namespace statsd { +// Helper functions for creating individual config components from StatsdConfig. +// Should only be called from metrics_manager_util and config_update_utils. + +// Create a LogMatchingTracker. +// input: +// [logMatcher]: the input AtomMatcher from the StatsdConfig +// [index]: the index of the matcher +// output: +// new LogMatchingTracker, or null if the tracker is unable to be created +sp<LogMatchingTracker> createLogTracker(const AtomMatcher& logMatcher, const int index, + const sp<UidMap>& uidMap); + // Helper functions for MetricsManager to initialize from StatsdConfig. // *Note*: only initStatsdConfig() should be called from outside. // All other functions are intermediate @@ -44,8 +56,7 @@ namespace statsd { // [logTrackerMap]: this map should contain matcher name to index mapping // [allAtomMatchers]: should store the sp to all the LogMatchingTracker // [allTagIds]: contains the set of all interesting tag ids to this config. -bool initLogTrackers(const StatsdConfig& config, - const UidMap& uidMap, +bool initLogTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap, std::unordered_map<int64_t, int>& logTrackerMap, std::vector<sp<LogMatchingTracker>>& allAtomMatchers, std::set<int>& allTagIds); @@ -97,7 +108,7 @@ bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAt // [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index. bool initMetrics( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs, - const int64_t currentTimeNs, UidMap& uidMap, const sp<StatsPullerManager>& pullerManager, + const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const std::unordered_map<int64_t, int>& logTrackerMap, const std::unordered_map<int64_t, int>& conditionTrackerMap, const std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks, @@ -116,12 +127,13 @@ bool initMetrics( // Initialize MetricsManager from StatsdConfig. // Parameters are the members of MetricsManager. See MetricsManager for declaration. -bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap, +bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, const int64_t currentTimeNs, std::set<int>& allTagIds, std::vector<sp<LogMatchingTracker>>& allAtomMatchers, + std::unordered_map<int64_t, int>& logTrackerMap, std::vector<sp<ConditionTracker>>& allConditionTrackers, std::vector<sp<MetricProducer>>& allMetricProducers, vector<sp<AnomalyTracker>>& allAnomalyTrackers, @@ -132,8 +144,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::unordered_map<int64_t, int>& alertTrackerMap, - vector<int>& metricsWithActivation, - std::set<int64_t>& noReportMetricIds); + vector<int>& metricsWithActivation, std::set<int64_t>& noReportMetricIds); } // namespace statsd } // namespace os diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp index fd883c29dba0..9d8f0c24e253 100644 --- a/cmds/statsd/src/shell/ShellSubscriber.cpp +++ b/cmds/statsd/src/shell/ShellSubscriber.cpp @@ -191,7 +191,7 @@ void ShellSubscriber::writePulledAtomsLocked(const vector<std::shared_ptr<LogEve mProto.clear(); int count = 0; for (const auto& event : data) { - if (matchesSimple(*mUidMap, matcher, *event)) { + if (matchesSimple(mUidMap, matcher, *event)) { count++; uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE | util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM); @@ -209,7 +209,7 @@ void ShellSubscriber::onLogEvent(const LogEvent& event) { mProto.clear(); for (const auto& matcher : mSubscriptionInfo->mPushedMatchers) { - if (matchesSimple(*mUidMap, matcher, event)) { + if (matchesSimple(mUidMap, matcher, event)) { uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE | util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM); event.ToProto(mProto); diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 6264c075426a..92cd04f37ee0 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -110,7 +110,7 @@ void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t ti } // anonymous namespace TEST(AtomMatcherTest, TestSimpleMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; @@ -129,7 +129,7 @@ TEST(AtomMatcherTest, TestSimpleMatcher) { } TEST(AtomMatcherTest, TestAttributionMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); std::vector<int> attributionUids = {1111, 2222, 3333}; std::vector<string> attributionTags = {"location1", "location2", "location3"}; @@ -204,7 +204,7 @@ TEST(AtomMatcherTest, TestAttributionMatcher) { "pkg0"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); - uidMap.updateMap( + uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, @@ -356,8 +356,8 @@ TEST(AtomMatcherTest, TestAttributionMatcher) { } TEST(AtomMatcherTest, TestUidFieldMatcher) { - UidMap uidMap; - uidMap.updateMap( + sp<UidMap> uidMap = new UidMap(); + uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, @@ -392,8 +392,8 @@ TEST(AtomMatcherTest, TestUidFieldMatcher) { } TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { - UidMap uidMap; - uidMap.updateMap( + sp<UidMap> uidMap = new UidMap(); + uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, @@ -453,8 +453,8 @@ TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { } TEST(AtomMatcherTest, TestEqAnyStringMatcher) { - UidMap uidMap; - uidMap.updateMap( + sp<UidMap> uidMap = new UidMap(); + uidMap->updateMap( 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("v1"), android::String16("v1"), android::String16("v2"), android::String16("v1"), android::String16("v2")}, @@ -517,7 +517,7 @@ TEST(AtomMatcherTest, TestEqAnyStringMatcher) { } TEST(AtomMatcherTest, TestBoolMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); @@ -550,7 +550,7 @@ TEST(AtomMatcherTest, TestBoolMatcher) { } TEST(AtomMatcherTest, TestStringMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); @@ -568,7 +568,7 @@ TEST(AtomMatcherTest, TestStringMatcher) { } TEST(AtomMatcherTest, TestMultiFieldsMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); @@ -597,7 +597,7 @@ TEST(AtomMatcherTest, TestMultiFieldsMatcher) { } TEST(AtomMatcherTest, TestIntComparisonMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); @@ -654,7 +654,7 @@ TEST(AtomMatcherTest, TestIntComparisonMatcher) { } TEST(AtomMatcherTest, TestFloatComparisonMatcher) { - UidMap uidMap; + sp<UidMap> uidMap = new UidMap(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp index 6259757fe092..8dd608347064 100644 --- a/cmds/statsd/tests/MetricsManager_test.cpp +++ b/cmds/statsd/tests/MetricsManager_test.cpp @@ -28,7 +28,7 @@ #include "src/metrics/GaugeMetricProducer.h" #include "src/metrics/MetricProducer.h" #include "src/metrics/ValueMetricProducer.h" -#include "src/metrics/metrics_manager_util.h" +#include "src/metrics/parsing_utils/metrics_manager_util.h" #include "src/state/StateManager.h" #include "statsd_test_util.h" @@ -48,7 +48,6 @@ namespace statsd { namespace { const ConfigKey kConfigKey(0, 12345); -const long kAlertId = 3; const long timeBaseSec = 1000; @@ -90,287 +89,6 @@ StatsdConfig buildGoodConfig() { metric->set_bucket(ONE_MINUTE); metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/); metric->mutable_dimensions_in_what()->add_child()->set_field(1); - - config.add_no_report_metric(3); - - auto alert = config.add_alert(); - alert->set_id(kAlertId); - alert->set_metric_id(3); - alert->set_num_buckets(10); - alert->set_refractory_period_secs(100); - alert->set_trigger_if_sum_gt(100); - return config; -} - -StatsdConfig buildCircleMatchers() { - StatsdConfig config; - config.set_id(12345); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_IS_ON")); - - SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); - simpleAtomMatcher->add_field_value_matcher()->set_field( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( - 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF")); - - AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); - combination->set_operation(LogicalOperation::OR); - combination->add_matcher(StringToId("SCREEN_IS_ON")); - // Circle dependency - combination->add_matcher(StringToId("SCREEN_ON_OR_OFF")); - - return config; -} - -StatsdConfig buildAlertWithUnknownMetric() { - StatsdConfig config; - config.set_id(12345); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_IS_ON")); - - CountMetric* metric = config.add_count_metric(); - metric->set_id(3); - metric->set_what(StringToId("SCREEN_IS_ON")); - metric->set_bucket(ONE_MINUTE); - metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/); - metric->mutable_dimensions_in_what()->add_child()->set_field(1); - - auto alert = config.add_alert(); - alert->set_id(3); - alert->set_metric_id(2); - alert->set_num_buckets(10); - alert->set_refractory_period_secs(100); - alert->set_trigger_if_sum_gt(100); - return config; -} - -StatsdConfig buildMissingMatchers() { - StatsdConfig config; - config.set_id(12345); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_IS_ON")); - - SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); - simpleAtomMatcher->add_field_value_matcher()->set_field( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( - 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF")); - - AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); - combination->set_operation(LogicalOperation::OR); - combination->add_matcher(StringToId("SCREEN_IS_ON")); - // undefined matcher - combination->add_matcher(StringToId("ABC")); - - return config; -} - -StatsdConfig buildMissingPredicate() { - StatsdConfig config; - config.set_id(12345); - - CountMetric* metric = config.add_count_metric(); - metric->set_id(3); - metric->set_what(StringToId("SCREEN_EVENT")); - metric->set_bucket(ONE_MINUTE); - metric->set_condition(StringToId("SOME_CONDITION")); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_EVENT")); - - SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2); - - return config; -} - -StatsdConfig buildDimensionMetricsWithMultiTags() { - StatsdConfig config; - config.set_id(12345); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("BATTERY_VERY_LOW")); - SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2); - - eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW")); - simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(3); - - eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("BATTERY_LOW")); - - AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); - combination->set_operation(LogicalOperation::OR); - combination->add_matcher(StringToId("BATTERY_VERY_LOW")); - combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW")); - - // Count process state changes, slice by uid, while SCREEN_IS_OFF - CountMetric* metric = config.add_count_metric(); - metric->set_id(3); - metric->set_what(StringToId("BATTERY_LOW")); - metric->set_bucket(ONE_MINUTE); - // This case is interesting. We want to dimension across two atoms. - metric->mutable_dimensions_in_what()->add_child()->set_field(1); - - auto alert = config.add_alert(); - alert->set_id(kAlertId); - alert->set_metric_id(3); - alert->set_num_buckets(10); - alert->set_refractory_period_secs(100); - alert->set_trigger_if_sum_gt(100); - return config; -} - -StatsdConfig buildCirclePredicates() { - StatsdConfig config; - config.set_id(12345); - - AtomMatcher* eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_IS_ON")); - - SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); - simpleAtomMatcher->add_field_value_matcher()->set_field( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( - 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - eventMatcher = config.add_atom_matcher(); - eventMatcher->set_id(StringToId("SCREEN_IS_OFF")); - - simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); - simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); - simpleAtomMatcher->add_field_value_matcher()->set_field( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/); - - auto condition = config.add_predicate(); - condition->set_id(StringToId("SCREEN_IS_ON")); - SimplePredicate* simplePredicate = condition->mutable_simple_predicate(); - simplePredicate->set_start(StringToId("SCREEN_IS_ON")); - simplePredicate->set_stop(StringToId("SCREEN_IS_OFF")); - - condition = config.add_predicate(); - condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF")); - - Predicate_Combination* combination = condition->mutable_combination(); - combination->set_operation(LogicalOperation::OR); - combination->add_predicate(StringToId("SCREEN_IS_ON")); - combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF")); - - return config; -} - -StatsdConfig buildConfigWithDifferentPredicates() { - StatsdConfig config; - config.set_id(12345); - - auto pulledAtomMatcher = - CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE); - *config.add_atom_matcher() = pulledAtomMatcher; - auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher(); - *config.add_atom_matcher() = screenOnAtomMatcher; - auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher(); - *config.add_atom_matcher() = screenOffAtomMatcher; - auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher(); - *config.add_atom_matcher() = batteryNoneAtomMatcher; - auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher(); - *config.add_atom_matcher() = batteryUsbAtomMatcher; - - // Simple condition with InitialValue set to default (unknown). - auto screenOnUnknownPredicate = CreateScreenIsOnPredicate(); - *config.add_predicate() = screenOnUnknownPredicate; - - // Simple condition with InitialValue set to false. - auto screenOnFalsePredicate = config.add_predicate(); - screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse")); - SimplePredicate* simpleScreenOnFalsePredicate = - screenOnFalsePredicate->mutable_simple_predicate(); - simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id()); - simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id()); - simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE); - - // Simple condition with InitialValue set to false. - auto onBatteryFalsePredicate = config.add_predicate(); - onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse")); - SimplePredicate* simpleOnBatteryFalsePredicate = - onBatteryFalsePredicate->mutable_simple_predicate(); - simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id()); - simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id()); - simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE); - - // Combination condition with both simple condition InitialValues set to false. - auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate(); - screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse")); - screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation( - LogicalOperation::AND); - addPredicateToPredicateCombination(*screenOnFalsePredicate, - screenOnFalseOnBatteryFalsePredicate); - addPredicateToPredicateCombination(*onBatteryFalsePredicate, - screenOnFalseOnBatteryFalsePredicate); - - // Combination condition with one simple condition InitialValue set to unknown and one set to - // false. - auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate(); - screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse")); - screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation( - LogicalOperation::AND); - addPredicateToPredicateCombination(screenOnUnknownPredicate, - screenOnUnknownOnBatteryFalsePredicate); - addPredicateToPredicateCombination(*onBatteryFalsePredicate, - screenOnUnknownOnBatteryFalsePredicate); - - // Simple condition metric with initial value false. - ValueMetric* metric1 = config.add_value_metric(); - metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse")); - metric1->set_what(pulledAtomMatcher.id()); - *metric1->mutable_value_field() = - CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); - metric1->set_bucket(FIVE_MINUTES); - metric1->set_condition(screenOnFalsePredicate->id()); - - // Simple condition metric with initial value unknown. - ValueMetric* metric2 = config.add_value_metric(); - metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown")); - metric2->set_what(pulledAtomMatcher.id()); - *metric2->mutable_value_field() = - CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); - metric2->set_bucket(FIVE_MINUTES); - metric2->set_condition(screenOnUnknownPredicate.id()); - - // Combination condition metric with initial values false and false. - ValueMetric* metric3 = config.add_value_metric(); - metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse")); - metric3->set_what(pulledAtomMatcher.id()); - *metric3->mutable_value_field() = - CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); - metric3->set_bucket(FIVE_MINUTES); - metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id()); - - // Combination condition metric with initial values unknown and false. - ValueMetric* metric4 = config.add_value_metric(); - metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse")); - metric4->set_what(pulledAtomMatcher.id()); - *metric4->mutable_value_field() = - CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); - metric4->set_bucket(FIVE_MINUTES); - metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id()); - return config; } @@ -379,274 +97,6 @@ bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) { } } // anonymous namespace -TEST(MetricsManagerTest, TestInitialConditions) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildConfigWithDifferentPredicates(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_TRUE(initStatsdConfig( - kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers, - allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap, - deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation, - noReportMetricIds)); - ASSERT_EQ(4u, allMetricProducers.size()); - ASSERT_EQ(5u, allConditionTrackers.size()); - - ConditionKey queryKey; - vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated); - - allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache); - allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache); - EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]); - EXPECT_EQ(ConditionState::kFalse, conditionCache[1]); - EXPECT_EQ(ConditionState::kFalse, conditionCache[2]); - EXPECT_EQ(ConditionState::kFalse, conditionCache[3]); - EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]); - - EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition); - EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition); - EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition); - EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition); -} - -TEST(MetricsManagerTest, TestGoodConfig) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildGoodConfig(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); - ASSERT_EQ(1u, allMetricProducers.size()); - ASSERT_EQ(1u, allAnomalyTrackers.size()); - ASSERT_EQ(1u, noReportMetricIds.size()); - ASSERT_EQ(1u, alertTrackerMap.size()); - EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end()); - EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0); -} - -TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildDimensionMetricsWithMultiTags(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); -} - -TEST(MetricsManagerTest, TestCircleLogMatcherDependency) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildCircleMatchers(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); -} - -TEST(MetricsManagerTest, TestMissingMatchers) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildMissingMatchers(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); -} - -TEST(MetricsManagerTest, TestMissingPredicate) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildMissingPredicate(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, noReportMetricIds)); -} - -TEST(MetricsManagerTest, TestCirclePredicateDependency) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildCirclePredicates(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); -} - -TEST(MetricsManagerTest, testAlertWithUnknownMetric) { - UidMap uidMap; - sp<StatsPullerManager> pullerManager = new StatsPullerManager(); - sp<AlarmMonitor> anomalyAlarmMonitor; - sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildAlertWithUnknownMetric(); - set<int> allTagIds; - vector<sp<LogMatchingTracker>> allAtomMatchers; - vector<sp<ConditionTracker>> allConditionTrackers; - vector<sp<MetricProducer>> allMetricProducers; - std::vector<sp<AnomalyTracker>> allAnomalyTrackers; - std::vector<sp<AlarmTracker>> allAlarmTrackers; - unordered_map<int, std::vector<int>> conditionToMetricMap; - unordered_map<int, std::vector<int>> trackerToMetricMap; - unordered_map<int, std::vector<int>> trackerToConditionMap; - unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; - unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; - unordered_map<int64_t, int> alertTrackerMap; - vector<int> metricsWithActivation; - std::set<int64_t> noReportMetricIds; - - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, - periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, - allAtomMatchers, allConditionTrackers, allMetricProducers, - allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, - trackerToMetricMap, trackerToConditionMap, - activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - alertTrackerMap, metricsWithActivation, - noReportMetricIds)); -} - TEST(MetricsManagerTest, TestLogSources) { string app1 = "app1"; set<int32_t> app1Uids = {1111, 11111}; @@ -680,7 +130,7 @@ TEST(MetricsManagerTest, TestLogSources) { sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildGoodConfig(); + StatsdConfig config; config.add_allowed_log_source("AID_SYSTEM"); config.add_allowed_log_source(app1); config.add_default_pull_packages("AID_SYSTEM"); @@ -744,7 +194,7 @@ TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) { sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; - StatsdConfig config = buildGoodConfig(); + StatsdConfig config; config.add_whitelisted_atom_ids(3); config.add_whitelisted_atom_ids(4); diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index caea42dfe032..d96ff8a1925b 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -47,7 +47,6 @@ namespace { const ConfigKey kConfigKey(0, 12345); const int tagId = 1; const int64_t metricId = 123; -const int64_t atomMatcherId = 678; const int logEventMatcherIndex = 0; const int64_t bucketStartTimeNs = 10 * NS_PER_SEC; const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; @@ -94,11 +93,8 @@ TEST(GaugeMetricProducerTest, TestFirstBucket) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); - sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({ - new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + sp<EventMatcherWizard> eventMatcherWizard = + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -127,12 +123,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -217,12 +209,8 @@ TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard, logEventMatcherIndex, eventMatcherWizard, @@ -301,12 +289,9 @@ TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return()); @@ -378,12 +363,8 @@ TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -428,12 +409,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); int64_t conditionChangeNs = bucketStartTimeNs + 8; @@ -502,12 +479,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) { dim->set_field(tagId); dim->add_child()->set_field(1); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); EXPECT_CALL(*wizard, query(_, _, _)) @@ -577,12 +550,8 @@ TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) { gaugeFieldMatcher->set_field(tagId); gaugeFieldMatcher->add_child()->set_field(2); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard, logEventMatcherIndex, eventMatcherWizard, tagId, -1, @@ -657,12 +626,8 @@ TEST(GaugeMetricProducerTest, TestPullOnTrigger) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) @@ -729,12 +694,8 @@ TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)) @@ -807,12 +768,8 @@ TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _)) diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index 98892507e78d..5524ebc86b36 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -46,7 +46,6 @@ namespace { const ConfigKey kConfigKey(0, 12345); const int tagId = 1; const int64_t metricId = 123; -const int64_t atomMatcherId = 678; const int logEventMatcherIndex = 0; const int64_t bucketStartTimeNs = 10000000000; const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL; @@ -99,12 +98,8 @@ class ValueMetricProducerTestHelper { public: static sp<ValueMetricProducer> createValueProducerNoConditions( sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) { - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)) .WillOnce(Return()); @@ -122,12 +117,8 @@ public: static sp<ValueMetricProducer> createValueProducerWithCondition( sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric, ConditionState conditionAfterFirstBucketPrepared) { - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)) .WillOnce(Return()); @@ -147,12 +138,8 @@ public: sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric, vector<int32_t> slicedStateAtoms, unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) { - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)) .WillOnce(Return()); @@ -172,12 +159,8 @@ public: vector<int32_t> slicedStateAtoms, unordered_map<int, unordered_map<int, int64_t>> stateGroupMap, ConditionState conditionAfterFirstBucketPrepared) { - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)) .WillOnce(Return()); @@ -237,12 +220,8 @@ TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); int64_t startTimeBase = 11; - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -267,12 +246,8 @@ TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) { TEST(ValueMetricProducerTest, TestFirstBucket) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -421,15 +396,11 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) { TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); - auto keyValue = atomMatcher.add_field_value_matcher(); - keyValue->set_field(1); - keyValue->set_eq_int(3); + FieldValueMatcher fvm; + fvm.set_field(1); + fvm.set_eq_int(3); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex, {fvm}); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -698,12 +669,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -759,12 +726,8 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) { TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150; @@ -820,12 +783,8 @@ TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); metric.set_split_bucket_for_app_upgrade(false); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -900,12 +859,8 @@ TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -944,12 +899,8 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1015,12 +966,8 @@ TEST(ValueMetricProducerTest, TestAnomalyDetection) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1360,12 +1307,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMin) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); metric.set_aggregation_type(ValueMetric::MIN); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1404,12 +1347,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); metric.set_aggregation_type(ValueMetric::MAX); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1447,12 +1386,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateAvg) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); metric.set_aggregation_type(ValueMetric::AVG); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1495,12 +1430,8 @@ TEST(ValueMetricProducerTest, TestPushedAggregateSum) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); metric.set_aggregation_type(ValueMetric::SUM); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1539,12 +1470,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { metric.set_aggregation_type(ValueMetric::MIN); metric.set_use_diff(true); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -1611,12 +1538,8 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) { metric.set_aggregation_type(ValueMetric::MIN); metric.set_use_diff(true); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); @@ -2140,12 +2063,8 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) { TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) { ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -2963,12 +2882,8 @@ TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) { TEST(ValueMetricProducerTest, TestPullNeededFastDump) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -3001,12 +2916,8 @@ TEST(ValueMetricProducerTest, TestPullNeededFastDump) { TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); @@ -3045,12 +2956,8 @@ TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) { TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) { ValueMetric metric = ValueMetricProducerTestHelper::createMetric(); - UidMap uidMap; - SimpleAtomMatcher atomMatcher; - atomMatcher.set_atom_id(tagId); sp<EventMatcherWizard> eventMatcherWizard = - new EventMatcherWizard({new SimpleLogMatchingTracker( - atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)}); + createEventMatcherWizard(tagId, logEventMatcherIndex); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return()); diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp new file mode 100644 index 000000000000..6b50fe5387d7 --- /dev/null +++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp @@ -0,0 +1,382 @@ +// Copyright (C) 2020 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 "src/metrics/parsing_utils/config_update_utils.h" + +#include <gtest/gtest.h> +#include <private/android_filesystem_config.h> +#include <stdio.h> + +#include <set> +#include <unordered_map> +#include <vector> + +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "src/metrics/parsing_utils/metrics_manager_util.h" +#include "tests/statsd_test_util.h" + +using namespace testing; +using android::sp; +using android::os::statsd::Predicate; +using std::map; +using std::set; +using std::unordered_map; +using std::vector; + +#ifdef __ANDROID__ + +namespace android { +namespace os { +namespace statsd { + +namespace { + +ConfigKey key(123, 456); +const int64_t timeBaseNs = 1000; +sp<UidMap> uidMap = new UidMap(); +sp<StatsPullerManager> pullerManager = new StatsPullerManager(); +sp<AlarmMonitor> anomalyAlarmMonitor; +sp<AlarmMonitor> periodicAlarmMonitor; +set<int> allTagIds; +vector<sp<LogMatchingTracker>> oldAtomMatchers; +unordered_map<int64_t, int> oldLogTrackerMap; +vector<sp<ConditionTracker>> oldConditionTrackers; +vector<sp<MetricProducer>> oldMetricProducers; +std::vector<sp<AnomalyTracker>> oldAnomalyTrackers; +std::vector<sp<AlarmTracker>> oldAlarmTrackers; +unordered_map<int, std::vector<int>> conditionToMetricMap; +unordered_map<int, std::vector<int>> trackerToMetricMap; +unordered_map<int, std::vector<int>> trackerToConditionMap; +unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; +unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; +unordered_map<int64_t, int> alertTrackerMap; +vector<int> metricsWithActivation; +std::set<int64_t> noReportMetricIds; + +class ConfigUpdateTest : public ::testing::Test { +public: + ConfigUpdateTest() { + } + + void SetUp() override { + allTagIds.clear(); + oldAtomMatchers.clear(); + oldLogTrackerMap.clear(); + oldConditionTrackers.clear(); + oldMetricProducers.clear(); + oldAnomalyTrackers.clear(); + oldAlarmTrackers.clear(); + conditionToMetricMap.clear(); + trackerToMetricMap.clear(); + trackerToConditionMap.clear(); + activationAtomTrackerToMetricMap.clear(); + deactivationAtomTrackerToMetricMap.clear(); + alertTrackerMap.clear(); + metricsWithActivation.clear(); + noReportMetricIds.clear(); + } +}; + +bool initConfig(const StatsdConfig& config) { + return initStatsdConfig(key, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseNs, timeBaseNs, allTagIds, + oldAtomMatchers, oldLogTrackerMap, oldConditionTrackers, + oldMetricProducers, oldAnomalyTrackers, oldAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + alertTrackerMap, metricsWithActivation, noReportMetricIds); +} + +} // anonymous namespace + +TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) { + StatsdConfig config; + AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10); + int64_t matcherId = matcher.id(); + *config.add_atom_matcher() = matcher; + + // Create an initial config. + EXPECT_TRUE(initConfig(config)); + + vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN); + vector<bool> cycleTracker(1, false); + unordered_map<int64_t, int> newLogTrackerMap; + newLogTrackerMap[matcherId] = 0; + EXPECT_TRUE(determineMatcherUpdateStatus(config, 0, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)); + EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE); +} + +TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) { + StatsdConfig config; + AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10); + *config.add_atom_matcher() = matcher; + + EXPECT_TRUE(initConfig(config)); + + StatsdConfig newConfig; + // Same id, different atom, so should be replaced. + AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11); + int64_t matcherId = newMatcher.id(); + EXPECT_EQ(matcherId, matcher.id()); + *newConfig.add_atom_matcher() = newMatcher; + + vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN); + vector<bool> cycleTracker(1, false); + unordered_map<int64_t, int> newLogTrackerMap; + newLogTrackerMap[matcherId] = 0; + EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)); + EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE); +} + +TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) { + StatsdConfig config; + AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11); + *config.add_atom_matcher() = matcher2; + int64_t matcher2Id = matcher2.id(); + + AtomMatcher matcher3; + matcher3.set_id(StringToId("TEST3")); + AtomMatcher_Combination* combination = matcher3.mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(matcher1Id); + combination->add_matcher(matcher2Id); + int64_t matcher3Id = matcher3.id(); + *config.add_atom_matcher() = matcher3; + + EXPECT_TRUE(initConfig(config)); + + StatsdConfig newConfig; + unordered_map<int64_t, int> newLogTrackerMap; + // Same matchers, different order, all should be preserved. + *newConfig.add_atom_matcher() = matcher2; + newLogTrackerMap[matcher2Id] = 0; + *newConfig.add_atom_matcher() = matcher3; + newLogTrackerMap[matcher3Id] = 1; + *newConfig.add_atom_matcher() = matcher1; + newLogTrackerMap[matcher1Id] = 2; + + vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN); + vector<bool> cycleTracker(3, false); + // Only update the combination. It should recurse the two child matchers and preserve all 3. + EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)); + EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE); + EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE); + EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE); +} + +TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) { + StatsdConfig config; + AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11); + *config.add_atom_matcher() = matcher2; + int64_t matcher2Id = matcher2.id(); + + AtomMatcher matcher3; + matcher3.set_id(StringToId("TEST3")); + AtomMatcher_Combination* combination = matcher3.mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(matcher1Id); + combination->add_matcher(matcher2Id); + int64_t matcher3Id = matcher3.id(); + *config.add_atom_matcher() = matcher3; + + EXPECT_TRUE(initConfig(config)); + + // Change the logical operation of the combination matcher, causing a replacement. + matcher3.mutable_combination()->set_operation(LogicalOperation::AND); + + StatsdConfig newConfig; + unordered_map<int64_t, int> newLogTrackerMap; + *newConfig.add_atom_matcher() = matcher2; + newLogTrackerMap[matcher2Id] = 0; + *newConfig.add_atom_matcher() = matcher3; + newLogTrackerMap[matcher3Id] = 1; + *newConfig.add_atom_matcher() = matcher1; + newLogTrackerMap[matcher1Id] = 2; + + vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN); + vector<bool> cycleTracker(3, false); + // Only update the combination. The simple matchers should not be evaluated. + EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)); + EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN); + EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE); + EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN); +} + +TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) { + StatsdConfig config; + AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11); + *config.add_atom_matcher() = matcher2; + int64_t matcher2Id = matcher2.id(); + + AtomMatcher matcher3; + matcher3.set_id(StringToId("TEST3")); + AtomMatcher_Combination* combination = matcher3.mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(matcher1Id); + combination->add_matcher(matcher2Id); + int64_t matcher3Id = matcher3.id(); + *config.add_atom_matcher() = matcher3; + + EXPECT_TRUE(initConfig(config)); + + // Change a dependency of matcher 3. + matcher2.mutable_simple_atom_matcher()->set_atom_id(12); + + StatsdConfig newConfig; + unordered_map<int64_t, int> newLogTrackerMap; + *newConfig.add_atom_matcher() = matcher2; + newLogTrackerMap[matcher2Id] = 0; + *newConfig.add_atom_matcher() = matcher3; + newLogTrackerMap[matcher3Id] = 1; + *newConfig.add_atom_matcher() = matcher1; + newLogTrackerMap[matcher1Id] = 2; + + vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN); + vector<bool> cycleTracker(3, false); + // Only update the combination. + EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldLogTrackerMap, oldAtomMatchers, + newLogTrackerMap, matchersToUpdate, cycleTracker)); + // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be. + EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE); + EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE); +} + +TEST_F(ConfigUpdateTest, TestUpdateMatchers) { + StatsdConfig config; + // Will be preserved. + AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10); + int64_t simple1Id = simple1.id(); + *config.add_atom_matcher() = simple1; + + // Will be replaced. + AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11); + *config.add_atom_matcher() = simple2; + int64_t simple2Id = simple2.id(); + + // Will be removed. + AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12); + *config.add_atom_matcher() = simple3; + int64_t simple3Id = simple3.id(); + + // Will be preserved. + AtomMatcher combination1; + combination1.set_id(StringToId("combination1")); + AtomMatcher_Combination* combination = combination1.mutable_combination(); + combination->set_operation(LogicalOperation::NOT); + combination->add_matcher(simple1Id); + int64_t combination1Id = combination1.id(); + *config.add_atom_matcher() = combination1; + + // Will be replaced since it depends on simple2. + AtomMatcher combination2; + combination2.set_id(StringToId("combination2")); + combination = combination2.mutable_combination(); + combination->set_operation(LogicalOperation::AND); + combination->add_matcher(simple1Id); + combination->add_matcher(simple2Id); + int64_t combination2Id = combination2.id(); + *config.add_atom_matcher() = combination2; + + EXPECT_TRUE(initConfig(config)); + + // Change simple2, causing simple2 and combination2 to be replaced. + simple2.mutable_simple_atom_matcher()->set_atom_id(111); + + // 2 new matchers: simple4 and combination3: + AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13); + int64_t simple4Id = simple4.id(); + + AtomMatcher combination3; + combination3.set_id(StringToId("combination3")); + combination = combination3.mutable_combination(); + combination->set_operation(LogicalOperation::AND); + combination->add_matcher(simple4Id); + combination->add_matcher(simple2Id); + int64_t combination3Id = combination3.id(); + + StatsdConfig newConfig; + *newConfig.add_atom_matcher() = combination3; + *newConfig.add_atom_matcher() = simple2; + *newConfig.add_atom_matcher() = combination2; + *newConfig.add_atom_matcher() = simple1; + *newConfig.add_atom_matcher() = simple4; + *newConfig.add_atom_matcher() = combination1; + + set<int> newTagIds; + unordered_map<int64_t, int> newLogTrackerMap; + vector<sp<LogMatchingTracker>> newAtomMatchers; + EXPECT_TRUE(updateLogTrackers(newConfig, uidMap, oldLogTrackerMap, oldAtomMatchers, newTagIds, + newLogTrackerMap, newAtomMatchers)); + + ASSERT_EQ(newTagIds.size(), 3); + EXPECT_EQ(newTagIds.count(10), 1); + EXPECT_EQ(newTagIds.count(111), 1); + EXPECT_EQ(newTagIds.count(13), 1); + + ASSERT_EQ(newLogTrackerMap.size(), 6); + EXPECT_EQ(newLogTrackerMap.at(combination3Id), 0); + EXPECT_EQ(newLogTrackerMap.at(simple2Id), 1); + EXPECT_EQ(newLogTrackerMap.at(combination2Id), 2); + EXPECT_EQ(newLogTrackerMap.at(simple1Id), 3); + EXPECT_EQ(newLogTrackerMap.at(simple4Id), 4); + EXPECT_EQ(newLogTrackerMap.at(combination1Id), 5); + + ASSERT_EQ(newAtomMatchers.size(), 6); + // Make sure all atom matchers are initialized: + for (const sp<LogMatchingTracker>& tracker : newAtomMatchers) { + EXPECT_TRUE(tracker->mInitialized); + } + // Make sure preserved atom matchers are the same. + EXPECT_EQ(oldAtomMatchers[oldLogTrackerMap.at(simple1Id)], + newAtomMatchers[newLogTrackerMap.at(simple1Id)]); + EXPECT_EQ(oldAtomMatchers[oldLogTrackerMap.at(combination1Id)], + newAtomMatchers[newLogTrackerMap.at(combination1Id)]); + // Make sure replaced matchers are different. + EXPECT_NE(oldAtomMatchers[oldLogTrackerMap.at(simple2Id)], + newAtomMatchers[newLogTrackerMap.at(simple2Id)]); + EXPECT_NE(oldAtomMatchers[oldLogTrackerMap.at(combination2Id)], + newAtomMatchers[newLogTrackerMap.at(combination2Id)]); + + // Validation, make sure the matchers have the proper ids. Could do more checks here. + EXPECT_EQ(newAtomMatchers[0]->getId(), combination3Id); + EXPECT_EQ(newAtomMatchers[1]->getId(), simple2Id); + EXPECT_EQ(newAtomMatchers[2]->getId(), combination2Id); + EXPECT_EQ(newAtomMatchers[3]->getId(), simple1Id); + EXPECT_EQ(newAtomMatchers[4]->getId(), simple4Id); + EXPECT_EQ(newAtomMatchers[5]->getId(), combination1Id); +} + +} // namespace statsd +} // namespace os +} // namespace android + +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp new file mode 100644 index 000000000000..4e97eaf6f149 --- /dev/null +++ b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp @@ -0,0 +1,708 @@ +// Copyright (C) 2020 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 "src/metrics/parsing_utils/metrics_manager_util.h" + +#include <gtest/gtest.h> +#include <private/android_filesystem_config.h> +#include <stdio.h> + +#include <set> +#include <unordered_map> +#include <vector> + +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "src/condition/ConditionTracker.h" +#include "src/matchers/LogMatchingTracker.h" +#include "src/metrics/CountMetricProducer.h" +#include "src/metrics/GaugeMetricProducer.h" +#include "src/metrics/MetricProducer.h" +#include "src/metrics/ValueMetricProducer.h" +#include "src/state/StateManager.h" +#include "tests/metrics/metrics_test_helper.h" +#include "tests/statsd_test_util.h" + +using namespace testing; +using android::sp; +using android::os::statsd::Predicate; +using std::map; +using std::set; +using std::unordered_map; +using std::vector; + +#ifdef __ANDROID__ + +namespace android { +namespace os { +namespace statsd { + +namespace { +const ConfigKey kConfigKey(0, 12345); +const long kAlertId = 3; + +const long timeBaseSec = 1000; + +StatsdConfig buildGoodConfig() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_ON")); + + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_OFF")); + + simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF")); + + AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(StringToId("SCREEN_IS_ON")); + combination->add_matcher(StringToId("SCREEN_IS_OFF")); + + CountMetric* metric = config.add_count_metric(); + metric->set_id(3); + metric->set_what(StringToId("SCREEN_IS_ON")); + metric->set_bucket(ONE_MINUTE); + metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/); + metric->mutable_dimensions_in_what()->add_child()->set_field(1); + + config.add_no_report_metric(3); + + auto alert = config.add_alert(); + alert->set_id(kAlertId); + alert->set_metric_id(3); + alert->set_num_buckets(10); + alert->set_refractory_period_secs(100); + alert->set_trigger_if_sum_gt(100); + return config; +} + +StatsdConfig buildCircleMatchers() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_ON")); + + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF")); + + AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(StringToId("SCREEN_IS_ON")); + // Circle dependency + combination->add_matcher(StringToId("SCREEN_ON_OR_OFF")); + + return config; +} + +StatsdConfig buildAlertWithUnknownMetric() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_ON")); + + CountMetric* metric = config.add_count_metric(); + metric->set_id(3); + metric->set_what(StringToId("SCREEN_IS_ON")); + metric->set_bucket(ONE_MINUTE); + metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/); + metric->mutable_dimensions_in_what()->add_child()->set_field(1); + + auto alert = config.add_alert(); + alert->set_id(3); + alert->set_metric_id(2); + alert->set_num_buckets(10); + alert->set_refractory_period_secs(100); + alert->set_trigger_if_sum_gt(100); + return config; +} + +StatsdConfig buildMissingMatchers() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_ON")); + + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF")); + + AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(StringToId("SCREEN_IS_ON")); + // undefined matcher + combination->add_matcher(StringToId("ABC")); + + return config; +} + +StatsdConfig buildMissingPredicate() { + StatsdConfig config; + config.set_id(12345); + + CountMetric* metric = config.add_count_metric(); + metric->set_id(3); + metric->set_what(StringToId("SCREEN_EVENT")); + metric->set_bucket(ONE_MINUTE); + metric->set_condition(StringToId("SOME_CONDITION")); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_EVENT")); + + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2); + + return config; +} + +StatsdConfig buildDimensionMetricsWithMultiTags() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("BATTERY_VERY_LOW")); + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW")); + simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(3); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("BATTERY_LOW")); + + AtomMatcher_Combination* combination = eventMatcher->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(StringToId("BATTERY_VERY_LOW")); + combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW")); + + // Count process state changes, slice by uid, while SCREEN_IS_OFF + CountMetric* metric = config.add_count_metric(); + metric->set_id(3); + metric->set_what(StringToId("BATTERY_LOW")); + metric->set_bucket(ONE_MINUTE); + // This case is interesting. We want to dimension across two atoms. + metric->mutable_dimensions_in_what()->add_child()->set_field(1); + + auto alert = config.add_alert(); + alert->set_id(kAlertId); + alert->set_metric_id(3); + alert->set_num_buckets(10); + alert->set_refractory_period_secs(100); + alert->set_trigger_if_sum_gt(100); + return config; +} + +StatsdConfig buildCirclePredicates() { + StatsdConfig config; + config.set_id(12345); + + AtomMatcher* eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_ON")); + + SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + eventMatcher = config.add_atom_matcher(); + eventMatcher->set_id(StringToId("SCREEN_IS_OFF")); + + simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/); + + auto condition = config.add_predicate(); + condition->set_id(StringToId("SCREEN_IS_ON")); + SimplePredicate* simplePredicate = condition->mutable_simple_predicate(); + simplePredicate->set_start(StringToId("SCREEN_IS_ON")); + simplePredicate->set_stop(StringToId("SCREEN_IS_OFF")); + + condition = config.add_predicate(); + condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF")); + + Predicate_Combination* combination = condition->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_predicate(StringToId("SCREEN_IS_ON")); + combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF")); + + return config; +} + +StatsdConfig buildConfigWithDifferentPredicates() { + StatsdConfig config; + config.set_id(12345); + + auto pulledAtomMatcher = + CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE); + *config.add_atom_matcher() = pulledAtomMatcher; + auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = screenOnAtomMatcher; + auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = screenOffAtomMatcher; + auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher(); + *config.add_atom_matcher() = batteryNoneAtomMatcher; + auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher(); + *config.add_atom_matcher() = batteryUsbAtomMatcher; + + // Simple condition with InitialValue set to default (unknown). + auto screenOnUnknownPredicate = CreateScreenIsOnPredicate(); + *config.add_predicate() = screenOnUnknownPredicate; + + // Simple condition with InitialValue set to false. + auto screenOnFalsePredicate = config.add_predicate(); + screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse")); + SimplePredicate* simpleScreenOnFalsePredicate = + screenOnFalsePredicate->mutable_simple_predicate(); + simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id()); + simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id()); + simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE); + + // Simple condition with InitialValue set to false. + auto onBatteryFalsePredicate = config.add_predicate(); + onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse")); + SimplePredicate* simpleOnBatteryFalsePredicate = + onBatteryFalsePredicate->mutable_simple_predicate(); + simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id()); + simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id()); + simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE); + + // Combination condition with both simple condition InitialValues set to false. + auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate(); + screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse")); + screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation( + LogicalOperation::AND); + addPredicateToPredicateCombination(*screenOnFalsePredicate, + screenOnFalseOnBatteryFalsePredicate); + addPredicateToPredicateCombination(*onBatteryFalsePredicate, + screenOnFalseOnBatteryFalsePredicate); + + // Combination condition with one simple condition InitialValue set to unknown and one set to + // false. + auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate(); + screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse")); + screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation( + LogicalOperation::AND); + addPredicateToPredicateCombination(screenOnUnknownPredicate, + screenOnUnknownOnBatteryFalsePredicate); + addPredicateToPredicateCombination(*onBatteryFalsePredicate, + screenOnUnknownOnBatteryFalsePredicate); + + // Simple condition metric with initial value false. + ValueMetric* metric1 = config.add_value_metric(); + metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse")); + metric1->set_what(pulledAtomMatcher.id()); + *metric1->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + metric1->set_bucket(FIVE_MINUTES); + metric1->set_condition(screenOnFalsePredicate->id()); + + // Simple condition metric with initial value unknown. + ValueMetric* metric2 = config.add_value_metric(); + metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown")); + metric2->set_what(pulledAtomMatcher.id()); + *metric2->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + metric2->set_bucket(FIVE_MINUTES); + metric2->set_condition(screenOnUnknownPredicate.id()); + + // Combination condition metric with initial values false and false. + ValueMetric* metric3 = config.add_value_metric(); + metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse")); + metric3->set_what(pulledAtomMatcher.id()); + *metric3->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + metric3->set_bucket(FIVE_MINUTES); + metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id()); + + // Combination condition metric with initial values unknown and false. + ValueMetric* metric4 = config.add_value_metric(); + metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse")); + metric4->set_what(pulledAtomMatcher.id()); + *metric4->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + metric4->set_bucket(FIVE_MINUTES); + metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id()); + + return config; +} +} // anonymous namespace + +TEST(MetricsManagerTest, TestInitialConditions) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildConfigWithDifferentPredicates(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_TRUE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); + ASSERT_EQ(4u, allMetricProducers.size()); + ASSERT_EQ(5u, allConditionTrackers.size()); + + ConditionKey queryKey; + vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated); + + allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache); + allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache); + EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]); + EXPECT_EQ(ConditionState::kFalse, conditionCache[1]); + EXPECT_EQ(ConditionState::kFalse, conditionCache[2]); + EXPECT_EQ(ConditionState::kFalse, conditionCache[3]); + EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]); + + EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition); + EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition); + EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition); + EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition); +} + +TEST(MetricsManagerTest, TestGoodConfig) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildGoodConfig(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_TRUE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); + ASSERT_EQ(1u, allMetricProducers.size()); + ASSERT_EQ(1u, allAnomalyTrackers.size()); + ASSERT_EQ(1u, noReportMetricIds.size()); + ASSERT_EQ(1u, alertTrackerMap.size()); + EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end()); + EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0); +} + +TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildDimensionMetricsWithMultiTags(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, TestCircleLogMatcherDependency) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildCircleMatchers(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, TestMissingMatchers) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildMissingMatchers(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, TestMissingPredicate) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildMissingPredicate(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, TestCirclePredicateDependency) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildCirclePredicates(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, testAlertWithUnknownMetric) { + sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> periodicAlarmMonitor; + StatsdConfig config = buildAlertWithUnknownMetric(); + set<int> allTagIds; + vector<sp<LogMatchingTracker>> allAtomMatchers; + unordered_map<int64_t, int> logTrackerMap; + vector<sp<ConditionTracker>> allConditionTrackers; + vector<sp<MetricProducer>> allMetricProducers; + std::vector<sp<AnomalyTracker>> allAnomalyTrackers; + std::vector<sp<AlarmTracker>> allAlarmTrackers; + unordered_map<int, std::vector<int>> conditionToMetricMap; + unordered_map<int, std::vector<int>> trackerToMetricMap; + unordered_map<int, std::vector<int>> trackerToConditionMap; + unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap; + unordered_map<int64_t, int> alertTrackerMap; + vector<int> metricsWithActivation; + std::set<int64_t> noReportMetricIds; + + EXPECT_FALSE(initStatsdConfig( + kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, logTrackerMap, + allConditionTrackers, allMetricProducers, allAnomalyTrackers, allAlarmTrackers, + conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap, + metricsWithActivation, noReportMetricIds)); +} + +TEST(MetricsManagerTest, TestCreateLogTrackerInvalidMatcher) { + sp<UidMap> uidMap = new UidMap(); + AtomMatcher matcher; + matcher.set_id(21); + EXPECT_EQ(createLogTracker(matcher, 0, uidMap), nullptr); +} + +TEST(MetricsManagerTest, TestCreateLogTrackerSimple) { + int index = 1; + int64_t id = 123; + sp<UidMap> uidMap = new UidMap(); + AtomMatcher matcher; + matcher.set_id(id); + SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher(); + simpleAtomMatcher->set_atom_id(util::SCREEN_STATE_CHANGED); + simpleAtomMatcher->add_field_value_matcher()->set_field( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int( + android::view::DisplayStateEnum::DISPLAY_STATE_ON); + + sp<LogMatchingTracker> tracker = createLogTracker(matcher, index, uidMap); + EXPECT_NE(tracker, nullptr); + + EXPECT_TRUE(tracker->mInitialized); + EXPECT_EQ(tracker->getId(), id); + EXPECT_EQ(tracker->mIndex, index); + const set<int>& atomIds = tracker->getAtomIds(); + ASSERT_EQ(atomIds.size(), 1); + EXPECT_EQ(atomIds.count(util::SCREEN_STATE_CHANGED), 1); +} + +TEST(MetricsManagerTest, TestCreateLogTrackerCombination) { + int index = 1; + int64_t id = 123; + sp<UidMap> uidMap = new UidMap(); + AtomMatcher matcher; + matcher.set_id(id); + AtomMatcher_Combination* combination = matcher.mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_matcher(123); + combination->add_matcher(223); + + sp<LogMatchingTracker> tracker = createLogTracker(matcher, index, uidMap); + EXPECT_NE(tracker, nullptr); + + // Combination matchers need to be initialized first. + EXPECT_FALSE(tracker->mInitialized); + EXPECT_EQ(tracker->getId(), id); + EXPECT_EQ(tracker->mIndex, index); + const set<int>& atomIds = tracker->getAtomIds(); + ASSERT_EQ(atomIds.size(), 0); +} + +} // namespace statsd +} // namespace os +} // namespace android + +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index cee83725d075..0be983f2a9b0 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -15,6 +15,8 @@ #include "statsd_test_util.h" #include <aidl/android/util/StatsEventParcel.h> + +#include "matchers/SimpleLogMatchingTracker.h" #include "stats_event.h" using aidl::android::util::StatsEventParcel; @@ -996,6 +998,20 @@ int64_t StringToId(const string& str) { return static_cast<int64_t>(std::hash<std::string>()(str)); } +sp<EventMatcherWizard> createEventMatcherWizard( + int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) { + sp<UidMap> uidMap = new UidMap(); + SimpleAtomMatcher atomMatcher; + atomMatcher.set_atom_id(tagId); + for (const FieldValueMatcher& fvm : fieldValueMatchers) { + *atomMatcher.add_field_value_matcher() = fvm; + } + uint64_t matcherHash = 0x12345678; + int64_t matcherId = 678; + return new EventMatcherWizard({new SimpleLogMatchingTracker(matcherId, matcherIndex, + matcherHash, atomMatcher, uidMap)}); +} + void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId, const int uid, const string& tag) { EXPECT_EQ(value.field(), atomId); diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index 3dcf4ecce054..1220019e2353 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -25,6 +25,7 @@ #include "src/StatsLogProcessor.h" #include "src/hash.h" #include "src/logd/LogEvent.h" +#include "src/matchers/EventMatcherWizard.h" #include "src/packages/UidMap.h" #include "src/stats_log_util.h" #include "stats_event.h" @@ -335,6 +336,9 @@ void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events); int64_t StringToId(const string& str); +sp<EventMatcherWizard> createEventMatcherWizard( + int tagId, int matcherIndex, const std::vector<FieldValueMatcher>& fieldValueMatchers = {}); + void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId, const int uid, const string& tag); void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid); |