1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/metrics/parsing_utils/metrics_manager_util.h"
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <private/android_filesystem_config.h>
20 #include <stdio.h>
21 
22 #include <set>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "src/condition/ConditionTracker.h"
27 #include "src/matchers/AtomMatchingTracker.h"
28 #include "src/metrics/CountMetricProducer.h"
29 #include "src/metrics/DurationMetricProducer.h"
30 #include "src/metrics/GaugeMetricProducer.h"
31 #include "src/metrics/KllMetricProducer.h"
32 #include "src/metrics/MetricProducer.h"
33 #include "src/metrics/NumericValueMetricProducer.h"
34 #include "src/state/StateManager.h"
35 #include "src/statsd_config.pb.h"
36 #include "tests/metrics/metrics_test_helper.h"
37 #include "tests/statsd_test_util.h"
38 
39 using namespace testing;
40 using android::sp;
41 using android::os::statsd::Predicate;
42 using std::map;
43 using std::set;
44 using std::unordered_map;
45 using std::vector;
46 
47 #ifdef __ANDROID__
48 
49 namespace android {
50 namespace os {
51 namespace statsd {
52 
53 namespace {
54 const int kConfigId = 12345;
55 const ConfigKey kConfigKey(0, kConfigId);
56 const long timeBaseSec = 1000;
57 const long kAlertId = 3;
58 
59 sp<UidMap> uidMap = new UidMap();
60 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
61 sp<AlarmMonitor> anomalyAlarmMonitor;
62 sp<AlarmMonitor> periodicAlarmMonitor;
63 sp<ConfigMetadataProvider> configMetadataProvider;
64 unordered_map<int, vector<int>> allTagIdsToMatchersMap;
65 vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
66 unordered_map<int64_t, int> atomMatchingTrackerMap;
67 vector<sp<ConditionTracker>> allConditionTrackers;
68 unordered_map<int64_t, int> conditionTrackerMap;
69 vector<sp<MetricProducer>> allMetricProducers;
70 unordered_map<int64_t, int> metricProducerMap;
71 vector<sp<AnomalyTracker>> allAnomalyTrackers;
72 unordered_map<int64_t, int> alertTrackerMap;
73 vector<sp<AlarmTracker>> allAlarmTrackers;
74 unordered_map<int, vector<int>> conditionToMetricMap;
75 unordered_map<int, vector<int>> trackerToMetricMap;
76 unordered_map<int, vector<int>> trackerToConditionMap;
77 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
78 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
79 vector<int> metricsWithActivation;
80 map<int64_t, uint64_t> stateProtoHashes;
81 set<int64_t> noReportMetricIds;
82 
initConfig(const StatsdConfig & config)83 optional<InvalidConfigReason> initConfig(const StatsdConfig& config) {
84     // initStatsdConfig returns nullopt if config is valid
85     return initStatsdConfig(
86             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
87             timeBaseSec, timeBaseSec, configMetadataProvider, allTagIdsToMatchersMap,
88             allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
89             conditionTrackerMap, allMetricProducers, metricProducerMap, allAnomalyTrackers,
90             allAlarmTrackers, conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
91             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, alertTrackerMap,
92             metricsWithActivation, stateProtoHashes, noReportMetricIds);
93 }
94 
buildCircleMatchers()95 StatsdConfig buildCircleMatchers() {
96     StatsdConfig config;
97     config.set_id(12345);
98 
99     AtomMatcher* eventMatcher = config.add_atom_matcher();
100     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
101 
102     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
103     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
104     simpleAtomMatcher->add_field_value_matcher()->set_field(
105             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
106     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
107             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
108 
109     eventMatcher = config.add_atom_matcher();
110     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
111 
112     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
113     combination->set_operation(LogicalOperation::OR);
114     combination->add_matcher(StringToId("SCREEN_IS_ON"));
115     // Circle dependency
116     combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
117 
118     return config;
119 }
120 
buildAlertWithUnknownMetric()121 StatsdConfig buildAlertWithUnknownMetric() {
122     StatsdConfig config;
123     config.set_id(12345);
124 
125     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
126 
127     CountMetric* metric = config.add_count_metric();
128     metric->set_id(3);
129     metric->set_what(StringToId("ScreenTurnedOn"));
130     metric->set_bucket(ONE_MINUTE);
131     metric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
132     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
133 
134     auto alert = config.add_alert();
135     alert->set_id(3);
136     alert->set_metric_id(2);
137     alert->set_num_buckets(10);
138     alert->set_refractory_period_secs(100);
139     alert->set_trigger_if_sum_gt(100);
140     return config;
141 }
142 
buildMissingMatchers()143 StatsdConfig buildMissingMatchers() {
144     StatsdConfig config;
145     config.set_id(12345);
146 
147     AtomMatcher* eventMatcher = config.add_atom_matcher();
148     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
149 
150     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
151     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
152     simpleAtomMatcher->add_field_value_matcher()->set_field(
153             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
154     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
155             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
156 
157     eventMatcher = config.add_atom_matcher();
158     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
159 
160     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
161     combination->set_operation(LogicalOperation::OR);
162     combination->add_matcher(StringToId("SCREEN_IS_ON"));
163     // undefined matcher
164     combination->add_matcher(StringToId("ABC"));
165 
166     return config;
167 }
168 
buildMissingPredicate()169 StatsdConfig buildMissingPredicate() {
170     StatsdConfig config;
171     config.set_id(12345);
172 
173     CountMetric* metric = config.add_count_metric();
174     metric->set_id(3);
175     metric->set_what(StringToId("SCREEN_EVENT"));
176     metric->set_bucket(ONE_MINUTE);
177     metric->set_condition(StringToId("SOME_CONDITION"));
178 
179     AtomMatcher* eventMatcher = config.add_atom_matcher();
180     eventMatcher->set_id(StringToId("SCREEN_EVENT"));
181 
182     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
183     simpleAtomMatcher->set_atom_id(2);
184 
185     return config;
186 }
187 
buildDimensionMetricsWithMultiTags()188 StatsdConfig buildDimensionMetricsWithMultiTags() {
189     StatsdConfig config;
190     config.set_id(12345);
191 
192     AtomMatcher* eventMatcher = config.add_atom_matcher();
193     eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
194     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
195     simpleAtomMatcher->set_atom_id(2);
196 
197     eventMatcher = config.add_atom_matcher();
198     eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
199     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
200     simpleAtomMatcher->set_atom_id(3);
201 
202     eventMatcher = config.add_atom_matcher();
203     eventMatcher->set_id(StringToId("BATTERY_LOW"));
204 
205     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
206     combination->set_operation(LogicalOperation::OR);
207     combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
208     combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
209 
210     // Count process state changes, slice by uid, while SCREEN_IS_OFF
211     CountMetric* metric = config.add_count_metric();
212     metric->set_id(3);
213     metric->set_what(StringToId("BATTERY_LOW"));
214     metric->set_bucket(ONE_MINUTE);
215     // This case is interesting. We want to dimension across two atoms.
216     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
217 
218     auto alert = config.add_alert();
219     alert->set_id(kAlertId);
220     alert->set_metric_id(3);
221     alert->set_num_buckets(10);
222     alert->set_refractory_period_secs(100);
223     alert->set_trigger_if_sum_gt(100);
224     return config;
225 }
226 
buildCirclePredicates()227 StatsdConfig buildCirclePredicates() {
228     StatsdConfig config;
229     config.set_id(12345);
230 
231     AtomMatcher* eventMatcher = config.add_atom_matcher();
232     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
233 
234     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
235     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
236     simpleAtomMatcher->add_field_value_matcher()->set_field(
237             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
238     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
239             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
240 
241     eventMatcher = config.add_atom_matcher();
242     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
243 
244     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
245     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
246     simpleAtomMatcher->add_field_value_matcher()->set_field(
247             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
248     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
249             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
250 
251     auto condition = config.add_predicate();
252     condition->set_id(StringToId("SCREEN_IS_ON"));
253     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
254     simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
255     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
256 
257     condition = config.add_predicate();
258     condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
259 
260     Predicate_Combination* combination = condition->mutable_combination();
261     combination->set_operation(LogicalOperation::OR);
262     combination->add_predicate(StringToId("SCREEN_IS_ON"));
263     combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
264 
265     return config;
266 }
267 
buildConfigWithDifferentPredicates()268 StatsdConfig buildConfigWithDifferentPredicates() {
269     StatsdConfig config;
270     config.set_id(12345);
271 
272     auto pulledAtomMatcher =
273             CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
274     *config.add_atom_matcher() = pulledAtomMatcher;
275     auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
276     *config.add_atom_matcher() = screenOnAtomMatcher;
277     auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
278     *config.add_atom_matcher() = screenOffAtomMatcher;
279     auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
280     *config.add_atom_matcher() = batteryNoneAtomMatcher;
281     auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
282     *config.add_atom_matcher() = batteryUsbAtomMatcher;
283 
284     // Simple condition with InitialValue set to default (unknown).
285     auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
286     *config.add_predicate() = screenOnUnknownPredicate;
287 
288     // Simple condition with InitialValue set to false.
289     auto screenOnFalsePredicate = config.add_predicate();
290     screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
291     SimplePredicate* simpleScreenOnFalsePredicate =
292             screenOnFalsePredicate->mutable_simple_predicate();
293     simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
294     simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
295     simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
296 
297     // Simple condition with InitialValue set to false.
298     auto onBatteryFalsePredicate = config.add_predicate();
299     onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
300     SimplePredicate* simpleOnBatteryFalsePredicate =
301             onBatteryFalsePredicate->mutable_simple_predicate();
302     simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
303     simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
304     simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
305 
306     // Combination condition with both simple condition InitialValues set to false.
307     auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
308     screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
309     screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
310             LogicalOperation::AND);
311     addPredicateToPredicateCombination(*screenOnFalsePredicate,
312                                        screenOnFalseOnBatteryFalsePredicate);
313     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
314                                        screenOnFalseOnBatteryFalsePredicate);
315 
316     // Combination condition with one simple condition InitialValue set to unknown and one set to
317     // false.
318     auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
319     screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
320     screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
321             LogicalOperation::AND);
322     addPredicateToPredicateCombination(screenOnUnknownPredicate,
323                                        screenOnUnknownOnBatteryFalsePredicate);
324     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
325                                        screenOnUnknownOnBatteryFalsePredicate);
326 
327     // Simple condition metric with initial value false.
328     ValueMetric* metric1 = config.add_value_metric();
329     metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
330     metric1->set_what(pulledAtomMatcher.id());
331     *metric1->mutable_value_field() =
332             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
333     metric1->set_bucket(FIVE_MINUTES);
334     metric1->set_condition(screenOnFalsePredicate->id());
335 
336     // Simple condition metric with initial value unknown.
337     ValueMetric* metric2 = config.add_value_metric();
338     metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
339     metric2->set_what(pulledAtomMatcher.id());
340     *metric2->mutable_value_field() =
341             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
342     metric2->set_bucket(FIVE_MINUTES);
343     metric2->set_condition(screenOnUnknownPredicate.id());
344 
345     // Combination condition metric with initial values false and false.
346     ValueMetric* metric3 = config.add_value_metric();
347     metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
348     metric3->set_what(pulledAtomMatcher.id());
349     *metric3->mutable_value_field() =
350             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
351     metric3->set_bucket(FIVE_MINUTES);
352     metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
353 
354     // Combination condition metric with initial values unknown and false.
355     ValueMetric* metric4 = config.add_value_metric();
356     metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
357     metric4->set_what(pulledAtomMatcher.id());
358     *metric4->mutable_value_field() =
359             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
360     metric4->set_bucket(FIVE_MINUTES);
361     metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
362 
363     return config;
364 }
365 
366 class MetricsManagerUtilTest : public ::testing::Test {
367 public:
SetUp()368     void SetUp() override {
369         allTagIdsToMatchersMap.clear();
370         allAtomMatchingTrackers.clear();
371         atomMatchingTrackerMap.clear();
372         allConditionTrackers.clear();
373         conditionTrackerMap.clear();
374         allMetricProducers.clear();
375         metricProducerMap.clear();
376         allAnomalyTrackers.clear();
377         allAlarmTrackers.clear();
378         conditionToMetricMap.clear();
379         trackerToMetricMap.clear();
380         trackerToConditionMap.clear();
381         activationAtomTrackerToMetricMap.clear();
382         deactivationAtomTrackerToMetricMap.clear();
383         alertTrackerMap.clear();
384         metricsWithActivation.clear();
385         stateProtoHashes.clear();
386         noReportMetricIds.clear();
387         StateManager::getInstance().clear();
388     }
389 };
390 
391 struct DimLimitTestCase {
392     int configLimit;
393     int actualLimit;
394 
PrintTo(const DimLimitTestCase & testCase,ostream * os)395     friend void PrintTo(const DimLimitTestCase& testCase, ostream* os) {
396         *os << testCase.configLimit;
397     }
398 };
399 
400 class MetricsManagerUtilDimLimitTest : public MetricsManagerUtilTest,
401                                        public WithParamInterface<DimLimitTestCase> {};
402 
403 const vector<DimLimitTestCase> dimLimitTestCases = {{900, 900}, {799, 800}, {3001, 3000}, {0, 800}};
404 
405 INSTANTIATE_TEST_SUITE_P(DimLimit, MetricsManagerUtilDimLimitTest, ValuesIn(dimLimitTestCases),
406                          PrintToStringParamName());
407 
408 }  // anonymous namespace
409 
TEST_F(MetricsManagerUtilTest,TestInitialConditions)410 TEST_F(MetricsManagerUtilTest, TestInitialConditions) {
411     // initConfig returns nullopt if config is valid
412     EXPECT_EQ(initConfig(buildConfigWithDifferentPredicates()), nullopt);
413     ASSERT_EQ(4u, allMetricProducers.size());
414     ASSERT_EQ(5u, allConditionTrackers.size());
415 
416     ConditionKey queryKey;
417     vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
418 
419     allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
420     allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
421     EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
422     EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
423     EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
424     EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
425     EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
426 
427     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
428     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
429     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
430     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
431 
432     EXPECT_EQ(allTagIdsToMatchersMap.size(), 3);
433     EXPECT_EQ(allTagIdsToMatchersMap[SCREEN_STATE_ATOM_ID].size(), 2);
434     EXPECT_EQ(allTagIdsToMatchersMap[util::PLUGGED_STATE_CHANGED].size(), 2);
435     EXPECT_EQ(allTagIdsToMatchersMap[util::SUBSYSTEM_SLEEP_STATE].size(), 1);
436 }
437 
TEST_F(MetricsManagerUtilTest,TestGoodConfig)438 TEST_F(MetricsManagerUtilTest, TestGoodConfig) {
439     StatsdConfig config = buildGoodConfig(kConfigId, kAlertId);
440     // initConfig returns nullopt if config is valid
441     EXPECT_EQ(initConfig(config), nullopt);
442     ASSERT_EQ(5u, allMetricProducers.size());
443     EXPECT_THAT(metricProducerMap, UnorderedElementsAre(Key(config.count_metric(0).id()),
444                                                         Key(config.duration_metric(0).id()),
445                                                         Key(config.value_metric(0).id()),
446                                                         Key(config.kll_metric(0).id()),
447                                                         Key(config.gauge_metric(0).id())));
448     ASSERT_EQ(1u, allAnomalyTrackers.size());
449     ASSERT_EQ(1u, noReportMetricIds.size());
450     ASSERT_EQ(1u, alertTrackerMap.size());
451     EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
452     EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
453 }
454 
TEST_F(MetricsManagerUtilTest,TestDimensionMetricsWithMultiTags)455 TEST_F(MetricsManagerUtilTest, TestDimensionMetricsWithMultiTags) {
456     EXPECT_EQ(initConfig(buildDimensionMetricsWithMultiTags()),
457               createInvalidConfigReasonWithMatcher(
458                       INVALID_CONFIG_REASON_METRIC_MATCHER_MORE_THAN_ONE_ATOM, /*metric id=*/3,
459                       StringToId("BATTERY_LOW")));
460 }
461 
TEST_F(MetricsManagerUtilTest,TestCircleLogMatcherDependency)462 TEST_F(MetricsManagerUtilTest, TestCircleLogMatcherDependency) {
463     optional<InvalidConfigReason> expectedInvalidConfigReason =
464             createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CYCLE,
465                                                  StringToId("SCREEN_ON_OR_OFF"));
466     expectedInvalidConfigReason->matcherIds.push_back(StringToId("SCREEN_ON_OR_OFF"));
467 
468     EXPECT_EQ(initConfig(buildCircleMatchers()), expectedInvalidConfigReason);
469 }
470 
TEST_F(MetricsManagerUtilTest,TestMissingMatchers)471 TEST_F(MetricsManagerUtilTest, TestMissingMatchers) {
472     optional<InvalidConfigReason> expectedInvalidConfigReason =
473             createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CHILD_NOT_FOUND,
474                                                  StringToId("SCREEN_ON_OR_OFF"));
475     expectedInvalidConfigReason->matcherIds.push_back(StringToId("ABC"));
476 
477     EXPECT_EQ(initConfig(buildMissingMatchers()), expectedInvalidConfigReason);
478 }
479 
TEST_F(MetricsManagerUtilTest,TestMissingPredicate)480 TEST_F(MetricsManagerUtilTest, TestMissingPredicate) {
481     EXPECT_EQ(
482             initConfig(buildMissingPredicate()),
483             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_METRIC_CONDITION_NOT_FOUND,
484                                                    /*metric id=*/3, StringToId("SOME_CONDITION")));
485 }
486 
TEST_F(MetricsManagerUtilTest,TestCirclePredicateDependency)487 TEST_F(MetricsManagerUtilTest, TestCirclePredicateDependency) {
488     optional<InvalidConfigReason> expectedInvalidConfigReason =
489             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CYCLE,
490                                                    StringToId("SCREEN_IS_EITHER_ON_OFF"));
491     expectedInvalidConfigReason->conditionIds.push_back(StringToId("SCREEN_IS_EITHER_ON_OFF"));
492 
493     EXPECT_EQ(initConfig(buildCirclePredicates()), expectedInvalidConfigReason);
494 }
495 
TEST_F(MetricsManagerUtilTest,TestAlertWithUnknownMetric)496 TEST_F(MetricsManagerUtilTest, TestAlertWithUnknownMetric) {
497     EXPECT_EQ(initConfig(buildAlertWithUnknownMetric()),
498               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
499                                                  /*metric id=*/2, /*matcher id=*/3));
500 }
501 
TEST_F(MetricsManagerUtilTest,TestMetricWithMultipleActivations)502 TEST_F(MetricsManagerUtilTest, TestMetricWithMultipleActivations) {
503     StatsdConfig config;
504     int64_t metricId = 1;
505     auto metric_activation1 = config.add_metric_activation();
506     metric_activation1->set_metric_id(metricId);
507     metric_activation1->set_activation_type(ACTIVATE_IMMEDIATELY);
508     auto metric_activation2 = config.add_metric_activation();
509     metric_activation2->set_metric_id(metricId);
510     metric_activation2->set_activation_type(ACTIVATE_IMMEDIATELY);
511 
512     EXPECT_EQ(initConfig(config),
513               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS, metricId));
514 }
515 
TEST_F(MetricsManagerUtilTest,TestCountMetricMissingIdOrWhat)516 TEST_F(MetricsManagerUtilTest, TestCountMetricMissingIdOrWhat) {
517     StatsdConfig config;
518     int64_t metricId = 1;
519     CountMetric* metric = config.add_count_metric();
520     metric->set_id(metricId);
521 
522     EXPECT_EQ(initConfig(config),
523               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
524 }
525 
TEST_F(MetricsManagerUtilTest,TestCountMetricConditionlinkNoCondition)526 TEST_F(MetricsManagerUtilTest, TestCountMetricConditionlinkNoCondition) {
527     StatsdConfig config;
528     CountMetric* metric = config.add_count_metric();
529     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
530                                 /*condition=*/nullopt, /*states=*/{});
531     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
532 
533     auto link = metric->add_links();
534     link->set_condition(1);
535 
536     EXPECT_EQ(initConfig(config),
537               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
538                                   StringToId("Count")));
539 }
540 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingIdOrWhat)541 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingIdOrWhat) {
542     StatsdConfig config;
543     int64_t metricId = 1;
544     DurationMetric* metric = config.add_duration_metric();
545     metric->set_id(metricId);
546 
547     EXPECT_EQ(initConfig(config),
548               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
549 }
550 
TEST_F(MetricsManagerUtilTest,TestDurationMetricConditionlinkNoCondition)551 TEST_F(MetricsManagerUtilTest, TestDurationMetricConditionlinkNoCondition) {
552     StatsdConfig config;
553     DurationMetric* metric = config.add_duration_metric();
554     *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
555                                    /*condition=*/nullopt, /*states=*/{});
556     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
557     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
558     *config.add_predicate() = CreateScreenIsOnPredicate();
559 
560     auto link = metric->add_links();
561     link->set_condition(1);
562 
563     EXPECT_EQ(initConfig(config),
564               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
565                                   StringToId("Duration")));
566 }
567 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricMissingIdOrWhat)568 TEST_F(MetricsManagerUtilTest, TestGaugeMetricMissingIdOrWhat) {
569     StatsdConfig config;
570     int64_t metricId = 1;
571     GaugeMetric* metric = config.add_gauge_metric();
572     metric->set_id(metricId);
573 
574     EXPECT_EQ(initConfig(config),
575               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
576 }
577 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricConditionlinkNoCondition)578 TEST_F(MetricsManagerUtilTest, TestGaugeMetricConditionlinkNoCondition) {
579     StatsdConfig config;
580     GaugeMetric* metric = config.add_gauge_metric();
581     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
582                                 /*samplingType=*/GaugeMetric_SamplingType_FIRST_N_SAMPLES,
583                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
584     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
585 
586     auto link = metric->add_links();
587     link->set_condition(1);
588 
589     EXPECT_EQ(initConfig(config),
590               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
591                                   StringToId("Gauge")));
592 }
593 
TEST_F(MetricsManagerUtilTest,TestEventMetricMissingIdOrWhat)594 TEST_F(MetricsManagerUtilTest, TestEventMetricMissingIdOrWhat) {
595     StatsdConfig config;
596     int64_t metricId = 1;
597     EventMetric* metric = config.add_event_metric();
598     metric->set_id(metricId);
599 
600     EXPECT_EQ(initConfig(config),
601               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
602 }
603 
TEST_F(MetricsManagerUtilTest,TestEventMetricConditionlinkNoCondition)604 TEST_F(MetricsManagerUtilTest, TestEventMetricConditionlinkNoCondition) {
605     StatsdConfig config;
606     EventMetric* metric = config.add_event_metric();
607     *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
608                                 /*condition=*/nullopt);
609     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
610 
611     auto link = metric->add_links();
612     link->set_condition(1);
613 
614     EXPECT_EQ(initConfig(config),
615               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
616                                   StringToId("Event")));
617 }
618 
TEST_F(MetricsManagerUtilTest,TestEventMetricInvalidSamplingPercentage)619 TEST_F(MetricsManagerUtilTest, TestEventMetricInvalidSamplingPercentage) {
620     StatsdConfig config;
621     EventMetric* metric = config.add_event_metric();
622     *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
623                                 /*condition=*/nullopt);
624     metric->set_sampling_percentage(101);
625     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
626 
627     EXPECT_EQ(initConfig(config),
628               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
629                                   StringToId("Event")));
630 }
631 
TEST_F(MetricsManagerUtilTest,TestEventMetricInvalidSamplingPercentageZero)632 TEST_F(MetricsManagerUtilTest, TestEventMetricInvalidSamplingPercentageZero) {
633     StatsdConfig config;
634     EventMetric* metric = config.add_event_metric();
635     *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
636                                 /*condition=*/nullopt);
637     metric->set_sampling_percentage(0);
638     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
639 
640     EXPECT_EQ(initConfig(config),
641               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
642                                   StringToId("Event")));
643 }
644 
TEST_F(MetricsManagerUtilTest,TestEventMetricValidSamplingPercentage)645 TEST_F(MetricsManagerUtilTest, TestEventMetricValidSamplingPercentage) {
646     StatsdConfig config;
647     EventMetric* metric = config.add_event_metric();
648     *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
649                                 /*condition=*/nullopt);
650     metric->set_sampling_percentage(50);
651     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
652 
653     EXPECT_EQ(initConfig(config), nullopt);
654 }
655 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidSamplingPercentage)656 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidSamplingPercentage) {
657     StatsdConfig config;
658     GaugeMetric* metric = config.add_gauge_metric();
659     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
660                                 GaugeMetric::FIRST_N_SAMPLES,
661                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
662     metric->set_sampling_percentage(101);
663     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
664 
665     EXPECT_EQ(initConfig(config),
666               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
667                                   StringToId("Gauge")));
668 }
669 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidSamplingPercentageZero)670 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidSamplingPercentageZero) {
671     StatsdConfig config;
672     GaugeMetric* metric = config.add_gauge_metric();
673     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
674                                 GaugeMetric::FIRST_N_SAMPLES,
675                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
676     metric->set_sampling_percentage(0);
677     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
678 
679     EXPECT_EQ(initConfig(config),
680               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
681                                   StringToId("Gauge")));
682 }
683 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricValidSamplingPercentage)684 TEST_F(MetricsManagerUtilTest, TestGaugeMetricValidSamplingPercentage) {
685     StatsdConfig config;
686     GaugeMetric* metric = config.add_gauge_metric();
687     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
688                                 GaugeMetric::FIRST_N_SAMPLES,
689                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
690     metric->set_sampling_percentage(50);
691     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
692 
693     EXPECT_EQ(initConfig(config), nullopt);
694 }
695 
TEST_F(MetricsManagerUtilTest,TestPulledGaugeMetricWithSamplingPercentage)696 TEST_F(MetricsManagerUtilTest, TestPulledGaugeMetricWithSamplingPercentage) {
697     StatsdConfig config;
698     GaugeMetric* metric = config.add_gauge_metric();
699     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
700                                 GaugeMetric::FIRST_N_SAMPLES,
701                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
702     metric->set_sampling_percentage(50);
703     *config.add_atom_matcher() =
704             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
705 
706     EXPECT_EQ(initConfig(config),
707               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_PULLED_WITH_SAMPLING,
708                                   StringToId("Gauge")));
709 }
710 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidPullProbability)711 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidPullProbability) {
712     StatsdConfig config;
713     GaugeMetric* metric = config.add_gauge_metric();
714     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
715                                 GaugeMetric::FIRST_N_SAMPLES,
716                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
717     metric->set_pull_probability(101);
718     *config.add_atom_matcher() =
719             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
720 
721     EXPECT_EQ(initConfig(config),
722               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_PULL_PROBABILITY,
723                                   StringToId("Gauge")));
724 }
725 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidPullProbabilityZero)726 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidPullProbabilityZero) {
727     StatsdConfig config;
728     GaugeMetric* metric = config.add_gauge_metric();
729     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
730                                 GaugeMetric::FIRST_N_SAMPLES,
731                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
732     metric->set_pull_probability(0);
733     *config.add_atom_matcher() =
734             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
735 
736     EXPECT_EQ(initConfig(config),
737               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_PULL_PROBABILITY,
738                                   StringToId("Gauge")));
739 }
740 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricValidPullProbability)741 TEST_F(MetricsManagerUtilTest, TestGaugeMetricValidPullProbability) {
742     StatsdConfig config;
743     GaugeMetric* metric = config.add_gauge_metric();
744     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
745                                 GaugeMetric::FIRST_N_SAMPLES,
746                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
747     metric->set_pull_probability(50);
748     *config.add_atom_matcher() =
749             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
750 
751     EXPECT_EQ(initConfig(config), nullopt);
752 }
753 
TEST_F(MetricsManagerUtilTest,TestPushedGaugeMetricWithPullProbability)754 TEST_F(MetricsManagerUtilTest, TestPushedGaugeMetricWithPullProbability) {
755     StatsdConfig config;
756     GaugeMetric* metric = config.add_gauge_metric();
757     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
758                                 GaugeMetric::FIRST_N_SAMPLES,
759                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
760     metric->set_pull_probability(50);
761     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
762 
763     EXPECT_EQ(initConfig(config),
764               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_PUSHED_WITH_PULL_PROBABILITY,
765                                   StringToId("Gauge")));
766 }
767 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricRandomOneSampleWithPullProbability)768 TEST_F(MetricsManagerUtilTest, TestGaugeMetricRandomOneSampleWithPullProbability) {
769     StatsdConfig config;
770     GaugeMetric* metric = config.add_gauge_metric();
771     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
772                                 GaugeMetric::RANDOM_ONE_SAMPLE,
773                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
774     metric->set_pull_probability(50);
775     *config.add_atom_matcher() =
776             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
777 
778     EXPECT_EQ(initConfig(config),
779               InvalidConfigReason(
780                       INVALID_CONFIG_REASON_GAUGE_METRIC_RANDOM_ONE_SAMPLE_WITH_PULL_PROBABILITY,
781                       StringToId("Gauge")));
782 }
783 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMissingIdOrWhat)784 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMissingIdOrWhat) {
785     StatsdConfig config;
786     int64_t metricId = 1;
787     ValueMetric* metric = config.add_value_metric();
788     metric->set_id(metricId);
789 
790     EXPECT_EQ(initConfig(config),
791               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
792 }
793 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricConditionlinkNoCondition)794 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricConditionlinkNoCondition) {
795     StatsdConfig config;
796     ValueMetric* metric = config.add_value_metric();
797     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
798                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
799     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
800 
801     auto link = metric->add_links();
802     link->set_condition(1);
803 
804     EXPECT_EQ(initConfig(config),
805               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
806                                   StringToId("NumericValue")));
807 }
808 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHasBothSingleAndMultipleAggTypes)809 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHasBothSingleAndMultipleAggTypes) {
810     StatsdConfig config;
811     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
812 
813     ValueMetric* metric = config.add_value_metric();
814     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
815                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
816     metric->set_aggregation_type(ValueMetric::SUM);
817     metric->add_aggregation_types(ValueMetric::SUM);
818     metric->add_aggregation_types(ValueMetric::MIN);
819 
820     EXPECT_EQ(initConfig(config),
821               InvalidConfigReason(
822                       INVALID_CONFIG_REASON_VALUE_METRIC_DEFINES_SINGLE_AND_MULTIPLE_AGG_TYPES,
823                       StringToId("NumericValue")));
824 }
825 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMoreAggTypesThanValueFields)826 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMoreAggTypesThanValueFields) {
827     StatsdConfig config;
828     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
829 
830     ValueMetric* metric = config.add_value_metric();
831     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
832                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
833     metric->add_aggregation_types(ValueMetric::SUM);
834     metric->add_aggregation_types(ValueMetric::MIN);
835 
836     EXPECT_EQ(
837             initConfig(config),
838             InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_AGG_TYPES_DNE_VALUE_FIELDS_SIZE,
839                                 StringToId("NumericValue")));
840 }
841 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMoreValueFieldsThanAggTypes)842 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMoreValueFieldsThanAggTypes) {
843     StatsdConfig config;
844     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
845 
846     ValueMetric* metric = config.add_value_metric();
847     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
848                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
849     // This only fails if the repeated aggregation field is used. If the single field is used,
850     // we will apply this aggregation type to all value fields.
851     metric->add_aggregation_types(ValueMetric::SUM);
852     metric->add_aggregation_types(ValueMetric::MIN);
853     *metric->mutable_value_field() = CreateDimensions(
854             util::SUBSYSTEM_SLEEP_STATE, {3 /* count */, 4 /* time_millis */, 3 /* count */});
855 
856     EXPECT_EQ(
857             initConfig(config),
858             InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_AGG_TYPES_DNE_VALUE_FIELDS_SIZE,
859                                 StringToId("NumericValue")));
860 }
861 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricDefaultAggTypeOutOfOrderFields)862 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricDefaultAggTypeOutOfOrderFields) {
863     StatsdConfig config;
864     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
865 
866     ValueMetric* metric = config.add_value_metric();
867     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
868                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
869     *metric->mutable_value_field() =
870             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time_millis */, 3 /* count */});
871 
872     EXPECT_EQ(initConfig(config), nullopt);
873 }
874 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMultipleAggTypesOutOfOrderFields)875 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMultipleAggTypesOutOfOrderFields) {
876     StatsdConfig config;
877     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
878 
879     ValueMetric* metric = config.add_value_metric();
880     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
881                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
882     metric->add_aggregation_types(ValueMetric::SUM);
883     metric->add_aggregation_types(ValueMetric::MIN);
884     metric->add_aggregation_types(ValueMetric::SUM);
885     *metric->mutable_value_field() = CreateDimensions(
886             util::SUBSYSTEM_SLEEP_STATE, {3 /* count */, 4 /* time_millis */, 3 /* count */});
887 
888     EXPECT_EQ(initConfig(config), nullopt);
889 }
890 
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingIdOrWhat)891 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingIdOrWhat) {
892     StatsdConfig config;
893     int64_t metricId = 1;
894     KllMetric* metric = config.add_kll_metric();
895     metric->set_id(metricId);
896 
897     EXPECT_EQ(initConfig(config),
898               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
899 }
900 
TEST_F(MetricsManagerUtilTest,TestKllMetricConditionlinkNoCondition)901 TEST_F(MetricsManagerUtilTest, TestKllMetricConditionlinkNoCondition) {
902     StatsdConfig config;
903     KllMetric* metric = config.add_kll_metric();
904     *metric = createKllMetric(/*name=*/"Kll", /*what=*/CreateScreenTurnedOnAtomMatcher(),
905                               /*valueField=*/2, /*condition=*/nullopt);
906     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
907 
908     auto link = metric->add_links();
909     link->set_condition(1);
910 
911     EXPECT_EQ(initConfig(config),
912               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
913                                   StringToId("Kll")));
914 }
915 
TEST_F(MetricsManagerUtilTest,TestMetricMatcherNotFound)916 TEST_F(MetricsManagerUtilTest, TestMetricMatcherNotFound) {
917     StatsdConfig config;
918     *config.add_count_metric() =
919             createCountMetric(/*name=*/"Count", /*what=*/StringToId("SOME MATCHER"),
920                               /*condition=*/nullopt, /*states=*/{});
921 
922     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
923                                           INVALID_CONFIG_REASON_METRIC_MATCHER_NOT_FOUND,
924                                           StringToId("Count"), StringToId("SOME MATCHER")));
925 }
926 
TEST_F(MetricsManagerUtilTest,TestMetricConditionLinkNotFound)927 TEST_F(MetricsManagerUtilTest, TestMetricConditionLinkNotFound) {
928     StatsdConfig config;
929     CountMetric* metric = config.add_count_metric();
930     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
931                                 /*condition=*/StringToId("ScreenIsOn"), /*states=*/{});
932     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
933     *config.add_predicate() = CreateScreenIsOnPredicate();
934 
935     auto link = metric->add_links();
936     link->set_condition(StringToId("SOME CONDITION"));
937 
938     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
939                                           INVALID_CONFIG_REASON_METRIC_CONDITION_LINK_NOT_FOUND,
940                                           StringToId("Count"), StringToId("SOME CONDITION")));
941 }
942 
TEST_F(MetricsManagerUtilTest,TestMetricStateNotFound)943 TEST_F(MetricsManagerUtilTest, TestMetricStateNotFound) {
944     StatsdConfig config;
945     *config.add_count_metric() =
946             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
947                               /*condition=*/nullopt, /*states=*/{StringToId("SOME STATE")});
948     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
949 
950     EXPECT_EQ(initConfig(config),
951               createInvalidConfigReasonWithState(INVALID_CONFIG_REASON_METRIC_STATE_NOT_FOUND,
952                                                  StringToId("Count"), StringToId("SOME STATE")));
953 }
954 
TEST_F(MetricsManagerUtilTest,TestMetricStatelinkNoState)955 TEST_F(MetricsManagerUtilTest, TestMetricStatelinkNoState) {
956     StatsdConfig config;
957     CountMetric* metric = config.add_count_metric();
958     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
959                                 /*condition=*/nullopt, /*states=*/{});
960     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
961 
962     auto link = metric->add_state_link();
963     link->set_state_atom_id(2);
964 
965     EXPECT_EQ(initConfig(config),
966               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE,
967                                   StringToId("Count")));
968 }
969 
TEST_F(MetricsManagerUtilTest,TestMetricBadThreshold)970 TEST_F(MetricsManagerUtilTest, TestMetricBadThreshold) {
971     StatsdConfig config;
972     CountMetric* metric = config.add_count_metric();
973     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
974                                 /*condition=*/nullopt, /*states=*/{});
975     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
976 
977     metric->mutable_threshold()->set_lt_float(1.0);
978 
979     EXPECT_EQ(initConfig(config),
980               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_BAD_THRESHOLD, StringToId("Count")));
981 }
982 
TEST_F(MetricsManagerUtilTest,TestMetricActivationMatcherNotFound)983 TEST_F(MetricsManagerUtilTest, TestMetricActivationMatcherNotFound) {
984     StatsdConfig config;
985     *config.add_count_metric() =
986             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
987                               /*condition=*/nullopt, /*states=*/{});
988     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
989     auto metric_activation = config.add_metric_activation();
990     metric_activation->set_metric_id(StringToId("Count"));
991     metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
992     auto event_activation = metric_activation->add_event_activation();
993 
994     event_activation->set_atom_matcher_id(StringToId("SOME_MATCHER"));
995 
996     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
997                                           INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND,
998                                           StringToId("Count"), StringToId("SOME_MATCHER")));
999 }
1000 
TEST_F(MetricsManagerUtilTest,TestMetricDeactivationMatcherNotFound)1001 TEST_F(MetricsManagerUtilTest, TestMetricDeactivationMatcherNotFound) {
1002     StatsdConfig config;
1003     *config.add_count_metric() =
1004             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
1005                               /*condition=*/nullopt, /*states=*/{});
1006     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1007     auto metric_activation = config.add_metric_activation();
1008     metric_activation->set_metric_id(StringToId("Count"));
1009     metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
1010     auto event_activation = metric_activation->add_event_activation();
1011     event_activation->set_atom_matcher_id(StringToId("ScreenTurnedOn"));
1012 
1013     event_activation->set_deactivation_atom_matcher_id(StringToId("SOME_MATCHER"));
1014 
1015     EXPECT_EQ(initConfig(config),
1016               createInvalidConfigReasonWithMatcher(
1017                       INVALID_CONFIG_REASON_METRIC_DEACTIVATION_MATCHER_NOT_FOUND,
1018                       StringToId("Count"), StringToId("SOME_MATCHER")));
1019 }
1020 
TEST_F(MetricsManagerUtilTest,TestMetricSlicedStateAtomAllowedFromAnyUid)1021 TEST_F(MetricsManagerUtilTest, TestMetricSlicedStateAtomAllowedFromAnyUid) {
1022     StatsdConfig config;
1023     CountMetric* metric = config.add_count_metric();
1024     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
1025                                 /*condition=*/nullopt, /*states=*/{});
1026     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1027 
1028     *config.add_state() = CreateScreenState();
1029     metric->add_slice_by_state(StringToId("ScreenState"));
1030     config.add_whitelisted_atom_ids(util::SCREEN_STATE_CHANGED);
1031 
1032     EXPECT_EQ(
1033             initConfig(config),
1034             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
1035                                 StringToId("Count")));
1036 }
1037 
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotSimple)1038 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotSimple) {
1039     StatsdConfig config;
1040     *config.add_duration_metric() =
1041             createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsEitherOnOff"),
1042                                  /*condition=*/nullopt, /*states=*/{});
1043     *config.add_predicate() = CreateScreenIsOnPredicate();
1044     *config.add_predicate() = CreateScreenIsOffPredicate();
1045 
1046     auto condition = config.add_predicate();
1047     condition->set_id(StringToId("ScreenIsEitherOnOff"));
1048     Predicate_Combination* combination = condition->mutable_combination();
1049     combination->set_operation(LogicalOperation::OR);
1050     combination->add_predicate(StringToId("ScreenIsOn"));
1051     combination->add_predicate(StringToId("ScreenIsOff"));
1052 
1053     EXPECT_EQ(initConfig(config),
1054               createInvalidConfigReasonWithPredicate(
1055                       INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_SIMPLE, StringToId("Duration"),
1056                       StringToId("ScreenIsEitherOnOff")));
1057 }
1058 
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotFound)1059 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotFound) {
1060     StatsdConfig config;
1061     int64_t metricId = 1;
1062     DurationMetric* metric = config.add_duration_metric();
1063     metric->set_id(metricId);
1064 
1065     metric->set_what(StringToId("SOME WHAT"));
1066 
1067     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
1068                                           INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_FOUND,
1069                                           metricId, StringToId("SOME WHAT")));
1070 }
1071 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingStart)1072 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingStart) {
1073     StatsdConfig config;
1074     *config.add_duration_metric() =
1075             createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("SCREEN_IS_ON"),
1076                                  /*condition=*/nullopt, /*states=*/{});
1077     auto condition = config.add_predicate();
1078     condition->set_id(StringToId("SCREEN_IS_ON"));
1079 
1080     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
1081     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
1082 
1083     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
1084                                           INVALID_CONFIG_REASON_DURATION_METRIC_MISSING_START,
1085                                           StringToId("Duration"), StringToId("SCREEN_IS_ON")));
1086 }
1087 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMaxSparseHasSpliceByState)1088 TEST_F(MetricsManagerUtilTest, TestDurationMetricMaxSparseHasSpliceByState) {
1089     StatsdConfig config;
1090     DurationMetric* metric = config.add_duration_metric();
1091     *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
1092                                    /*condition=*/nullopt, /*states=*/{});
1093     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1094     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
1095     *config.add_predicate() = CreateScreenIsOnPredicate();
1096     *config.add_state() = CreateScreenState();
1097 
1098     metric->add_slice_by_state(StringToId("ScreenState"));
1099     metric->set_aggregation_type(DurationMetric::MAX_SPARSE);
1100 
1101     EXPECT_EQ(
1102             initConfig(config),
1103             InvalidConfigReason(INVALID_CONFIG_REASON_DURATION_METRIC_MAX_SPARSE_HAS_SLICE_BY_STATE,
1104                                 StringToId("Duration")));
1105 }
1106 
TEST_F(MetricsManagerUtilTest,TestValueMetricMissingValueField)1107 TEST_F(MetricsManagerUtilTest, TestValueMetricMissingValueField) {
1108     StatsdConfig config;
1109     int64_t metricId = 1;
1110     ValueMetric* metric = config.add_value_metric();
1111     metric->set_id(metricId);
1112     metric->set_what(1);
1113 
1114     EXPECT_EQ(
1115             initConfig(config),
1116             InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_MISSING_VALUE_FIELD, metricId));
1117 }
1118 
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasPositionAll)1119 TEST_F(MetricsManagerUtilTest, TestValueMetricValueFieldHasPositionAll) {
1120     StatsdConfig config;
1121     int64_t metricId = 1;
1122     ValueMetric* metric = config.add_value_metric();
1123     metric->set_id(metricId);
1124     metric->set_what(1);
1125 
1126     metric->mutable_value_field()->set_position(ALL);
1127 
1128     EXPECT_EQ(initConfig(config),
1129               InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL,
1130                                   metricId));
1131 }
1132 
TEST_F(MetricsManagerUtilTest,TestValueMetricHasIncorrectValueField)1133 TEST_F(MetricsManagerUtilTest, TestValueMetricHasIncorrectValueField) {
1134     StatsdConfig config;
1135     int64_t metricId = 1;
1136     ValueMetric* metric = config.add_value_metric();
1137     metric->set_id(metricId);
1138     metric->set_what(1);
1139 
1140     metric->mutable_value_field()->set_position(ANY);
1141 
1142     EXPECT_EQ(initConfig(config),
1143               InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HAS_INCORRECT_VALUE_FIELD,
1144                                   metricId));
1145 }
1146 
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingKllField)1147 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingKllField) {
1148     StatsdConfig config;
1149     int64_t metricId = 1;
1150     KllMetric* metric = config.add_kll_metric();
1151     metric->set_id(metricId);
1152     metric->set_what(1);
1153 
1154     EXPECT_EQ(initConfig(config),
1155               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_MISSING_KLL_FIELD, metricId));
1156 }
1157 
TEST_F(MetricsManagerUtilTest,TestKllMetricKllFieldHasPositionAll)1158 TEST_F(MetricsManagerUtilTest, TestKllMetricKllFieldHasPositionAll) {
1159     StatsdConfig config;
1160     int64_t metricId = 1;
1161     KllMetric* metric = config.add_kll_metric();
1162     metric->set_id(metricId);
1163     metric->set_what(1);
1164 
1165     metric->mutable_kll_field()->set_position(ALL);
1166 
1167     EXPECT_EQ(initConfig(config),
1168               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_KLL_FIELD_HAS_POSITION_ALL,
1169                                   metricId));
1170 }
1171 
TEST_F(MetricsManagerUtilTest,TestKllMetricHasIncorrectKllField)1172 TEST_F(MetricsManagerUtilTest, TestKllMetricHasIncorrectKllField) {
1173     StatsdConfig config;
1174     int64_t metricId = 1;
1175     KllMetric* metric = config.add_kll_metric();
1176     metric->set_id(metricId);
1177     metric->set_what(1);
1178 
1179     metric->mutable_kll_field()->set_position(ANY);
1180 
1181     EXPECT_EQ(initConfig(config),
1182               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_HAS_INCORRECT_KLL_FIELD,
1183                                   metricId));
1184 }
1185 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricIncorrectFieldFilter)1186 TEST_F(MetricsManagerUtilTest, TestGaugeMetricIncorrectFieldFilter) {
1187     StatsdConfig config;
1188     int64_t metricId = 1;
1189     GaugeMetric* metric = config.add_gauge_metric();
1190     metric->set_id(metricId);
1191     metric->set_what(1);
1192 
1193     EXPECT_EQ(initConfig(config),
1194               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_INCORRECT_FIELD_FILTER,
1195                                   metricId));
1196 }
1197 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoPullAtom)1198 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoPullAtom) {
1199     StatsdConfig config;
1200     int64_t metricId = 1;
1201     GaugeMetric* metric = config.add_gauge_metric();
1202     metric->set_id(metricId);
1203     metric->set_what(StringToId("ScreenTurnedOn"));
1204     metric->mutable_gauge_fields_filter()->set_include_all(true);
1205     metric->set_trigger_event(1);
1206 
1207     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1208 
1209     EXPECT_EQ(
1210             initConfig(config),
1211             InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_PULL_ATOM, metricId));
1212 }
1213 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoFirstNSamples)1214 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoFirstNSamples) {
1215     StatsdConfig config;
1216     int64_t metricId = 1;
1217     GaugeMetric* metric = config.add_gauge_metric();
1218     metric->set_id(metricId);
1219     metric->set_what(StringToId("Matcher"));
1220     *config.add_atom_matcher() =
1221             CreateSimpleAtomMatcher(/*name=*/"Matcher", /*atomId=*/util::SUBSYSTEM_SLEEP_STATE);
1222 
1223     metric->mutable_gauge_fields_filter()->set_include_all(true);
1224     metric->set_trigger_event(StringToId("Matcher"));
1225 
1226     EXPECT_EQ(initConfig(config),
1227               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_FIRST_N_SAMPLES,
1228                                   metricId));
1229 }
1230 
TEST_F(MetricsManagerUtilTest,TestMatcherDuplicate)1231 TEST_F(MetricsManagerUtilTest, TestMatcherDuplicate) {
1232     StatsdConfig config;
1233 
1234     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1235     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1236 
1237     EXPECT_EQ(initConfig(config),
1238               createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
1239                                                    StringToId("ScreenTurnedOn")));
1240 }
1241 
TEST_F(MetricsManagerUtilTest,TestMatcherNoOperation)1242 TEST_F(MetricsManagerUtilTest, TestMatcherNoOperation) {
1243     StatsdConfig config;
1244     int64_t matcherId = 1;
1245 
1246     AtomMatcher* matcher = config.add_atom_matcher();
1247     matcher->set_id(matcherId);
1248     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1249 
1250     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
1251                                           INVALID_CONFIG_REASON_MATCHER_NO_OPERATION, matcherId));
1252 }
1253 
TEST_F(MetricsManagerUtilTest,TestMatcherNotOperationIsNotUnary)1254 TEST_F(MetricsManagerUtilTest, TestMatcherNotOperationIsNotUnary) {
1255     StatsdConfig config;
1256     int64_t matcherId = 1;
1257     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1258     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
1259 
1260     AtomMatcher* matcher = config.add_atom_matcher();
1261     matcher->set_id(matcherId);
1262     matcher->mutable_combination()->set_operation(LogicalOperation::NOT);
1263     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1264     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOff"));
1265 
1266     EXPECT_EQ(initConfig(config),
1267               createInvalidConfigReasonWithMatcher(
1268                       INVALID_CONFIG_REASON_MATCHER_NOT_OPERATION_IS_NOT_UNARY, matcherId));
1269 }
1270 
TEST_F(MetricsManagerUtilTest,TestConditionChildNotFound)1271 TEST_F(MetricsManagerUtilTest, TestConditionChildNotFound) {
1272     StatsdConfig config;
1273     int64_t conditionId = 1;
1274     int64_t childConditionId = 2;
1275 
1276     Predicate* condition = config.add_predicate();
1277     condition->set_id(conditionId);
1278     condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1279     condition->mutable_combination()->add_predicate(childConditionId);
1280 
1281     optional<InvalidConfigReason> expectedInvalidConfigReason =
1282             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CHILD_NOT_FOUND,
1283                                                    conditionId);
1284     expectedInvalidConfigReason->conditionIds.push_back(childConditionId);
1285     EXPECT_EQ(initConfig(config), expectedInvalidConfigReason);
1286 }
1287 
TEST_F(MetricsManagerUtilTest,TestConditionDuplicate)1288 TEST_F(MetricsManagerUtilTest, TestConditionDuplicate) {
1289     StatsdConfig config;
1290     *config.add_predicate() = CreateScreenIsOnPredicate();
1291     *config.add_predicate() = CreateScreenIsOnPredicate();
1292 
1293     EXPECT_EQ(initConfig(config),
1294               createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
1295                                                      StringToId("ScreenIsOn")));
1296 }
1297 
TEST_F(MetricsManagerUtilTest,TestConditionNoOperation)1298 TEST_F(MetricsManagerUtilTest, TestConditionNoOperation) {
1299     StatsdConfig config;
1300     int64_t conditionId = 1;
1301     *config.add_predicate() = CreateScreenIsOnPredicate();
1302 
1303     Predicate* condition = config.add_predicate();
1304     condition->set_id(conditionId);
1305     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1306 
1307     EXPECT_EQ(initConfig(config),
1308               createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_NO_OPERATION,
1309                                                      conditionId));
1310 }
1311 
TEST_F(MetricsManagerUtilTest,TestConditionNotOperationIsNotUnary)1312 TEST_F(MetricsManagerUtilTest, TestConditionNotOperationIsNotUnary) {
1313     StatsdConfig config;
1314     int64_t conditionId = 1;
1315     *config.add_predicate() = CreateScreenIsOnPredicate();
1316     *config.add_predicate() = CreateScreenIsOffPredicate();
1317 
1318     Predicate* condition = config.add_predicate();
1319     condition->set_id(conditionId);
1320     condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1321     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1322     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOff"));
1323 
1324     EXPECT_EQ(initConfig(config),
1325               createInvalidConfigReasonWithPredicate(
1326                       INVALID_CONFIG_REASON_CONDITION_NOT_OPERATION_IS_NOT_UNARY, conditionId));
1327 }
1328 
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlert)1329 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlert) {
1330     StatsdConfig config;
1331     int64_t alertId = 1;
1332     *config.add_subscription() = createSubscription("Subscription", Subscription::ALERT, alertId);
1333 
1334     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlert(
1335                                           INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1336                                           StringToId("Subscription"), alertId));
1337 }
1338 
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlarm)1339 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlarm) {
1340     StatsdConfig config;
1341     int64_t alarmId = 1;
1342     *config.add_subscription() = createSubscription("Subscription", Subscription::ALARM, alarmId);
1343 
1344     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlarm(
1345                                           INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1346                                           StringToId("Subscription"), alarmId));
1347 }
1348 
TEST_F(MetricsManagerUtilTest,TestSubscriptionSubscriberInfoMissing)1349 TEST_F(MetricsManagerUtilTest, TestSubscriptionSubscriberInfoMissing) {
1350     StatsdConfig config;
1351     Subscription subscription =
1352             createSubscription("Subscription", Subscription::ALERT, /*alert id=*/1);
1353     subscription.clear_subscriber_information();
1354     *config.add_subscription() = subscription;
1355 
1356     EXPECT_EQ(initConfig(config),
1357               createInvalidConfigReasonWithSubscription(
1358                       INVALID_CONFIG_REASON_SUBSCRIPTION_SUBSCRIBER_INFO_MISSING,
1359                       StringToId("Subscription")));
1360 }
1361 
TEST_F(MetricsManagerUtilTest,TestAlarmPeriodLessThanOrEqualZero)1362 TEST_F(MetricsManagerUtilTest, TestAlarmPeriodLessThanOrEqualZero) {
1363     StatsdConfig config;
1364     *config.add_alarm() = createAlarm("Alarm", /*offset=*/1, /*period=*/-1);
1365 
1366     EXPECT_EQ(initConfig(config),
1367               createInvalidConfigReasonWithAlarm(
1368                       INVALID_CONFIG_REASON_ALARM_PERIOD_LESS_THAN_OR_EQUAL_ZERO,
1369                       StringToId("Alarm")));
1370 }
1371 
TEST_F(MetricsManagerUtilTest,TestAlarmOffsetLessThanOrEqualZero)1372 TEST_F(MetricsManagerUtilTest, TestAlarmOffsetLessThanOrEqualZero) {
1373     StatsdConfig config;
1374     *config.add_alarm() = createAlarm("Alarm", /*offset=*/-1, /*period=*/1);
1375 
1376     EXPECT_EQ(initConfig(config),
1377               createInvalidConfigReasonWithAlarm(
1378                       INVALID_CONFIG_REASON_ALARM_OFFSET_LESS_THAN_OR_EQUAL_ZERO,
1379                       StringToId("Alarm")));
1380 }
1381 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerInvalidMatcher)1382 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerInvalidMatcher) {
1383     sp<UidMap> uidMap = new UidMap();
1384     AtomMatcher matcher;
1385     // Matcher has no contents_case (simple/combination), so it is invalid.
1386     matcher.set_id(21);
1387     optional<InvalidConfigReason> invalidConfigReason;
1388     EXPECT_EQ(createAtomMatchingTracker(matcher, uidMap, invalidConfigReason), nullptr);
1389     EXPECT_EQ(invalidConfigReason,
1390               createInvalidConfigReasonWithMatcher(
1391                       INVALID_CONFIG_REASON_MATCHER_MALFORMED_CONTENTS_CASE, matcher.id()));
1392 }
1393 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerSimple)1394 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerSimple) {
1395     int64_t id = 123;
1396     sp<UidMap> uidMap = new UidMap();
1397     AtomMatcher matcher;
1398     matcher.set_id(id);
1399     SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
1400     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
1401     simpleAtomMatcher->add_field_value_matcher()->set_field(
1402             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
1403     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
1404             android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1405 
1406     optional<InvalidConfigReason> invalidConfigReason;
1407     sp<AtomMatchingTracker> tracker =
1408             createAtomMatchingTracker(matcher, uidMap, invalidConfigReason);
1409     EXPECT_NE(tracker, nullptr);
1410     EXPECT_EQ(invalidConfigReason, nullopt);
1411 
1412     EXPECT_TRUE(tracker->mInitialized);
1413     EXPECT_EQ(tracker->getId(), id);
1414     const set<int>& atomIds = tracker->getAtomIds();
1415     ASSERT_EQ(atomIds.size(), 1);
1416     EXPECT_EQ(atomIds.count(SCREEN_STATE_ATOM_ID), 1);
1417 }
1418 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerCombination)1419 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerCombination) {
1420     int64_t id = 123;
1421     sp<UidMap> uidMap = new UidMap();
1422     AtomMatcher matcher;
1423     matcher.set_id(id);
1424     AtomMatcher_Combination* combination = matcher.mutable_combination();
1425     combination->set_operation(LogicalOperation::OR);
1426     combination->add_matcher(123);
1427     combination->add_matcher(223);
1428 
1429     optional<InvalidConfigReason> invalidConfigReason;
1430     sp<AtomMatchingTracker> tracker =
1431             createAtomMatchingTracker(matcher, uidMap, invalidConfigReason);
1432     EXPECT_NE(tracker, nullptr);
1433     EXPECT_EQ(invalidConfigReason, nullopt);
1434 
1435     // Combination matchers need to be initialized first.
1436     EXPECT_FALSE(tracker->mInitialized);
1437     EXPECT_EQ(tracker->getId(), id);
1438     const set<int>& atomIds = tracker->getAtomIds();
1439     ASSERT_EQ(atomIds.size(), 0);
1440 }
1441 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerInvalid)1442 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerInvalid) {
1443     const ConfigKey key(123, 456);
1444     // Predicate has no contents_case (simple/combination), so it is invalid.
1445     Predicate predicate;
1446     predicate.set_id(21);
1447     unordered_map<int64_t, int> atomTrackerMap;
1448     optional<InvalidConfigReason> invalidConfigReason;
1449     EXPECT_EQ(createConditionTracker(key, predicate, 0, atomTrackerMap, invalidConfigReason),
1450               nullptr);
1451     EXPECT_EQ(invalidConfigReason,
1452               createInvalidConfigReasonWithPredicate(
1453                       INVALID_CONFIG_REASON_CONDITION_MALFORMED_CONTENTS_CASE, predicate.id()));
1454 }
1455 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerSimple)1456 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerSimple) {
1457     int index = 1;
1458     int64_t id = 987;
1459     const ConfigKey key(123, 456);
1460 
1461     int startMatcherIndex = 2, stopMatcherIndex = 0, stopAllMatcherIndex = 1;
1462     int64_t startMatcherId = 246, stopMatcherId = 153, stopAllMatcherId = 975;
1463 
1464     Predicate predicate;
1465     predicate.set_id(id);
1466     SimplePredicate* simplePredicate = predicate.mutable_simple_predicate();
1467     simplePredicate->set_start(startMatcherId);
1468     simplePredicate->set_stop(stopMatcherId);
1469     simplePredicate->set_stop_all(stopAllMatcherId);
1470 
1471     unordered_map<int64_t, int> atomTrackerMap;
1472     atomTrackerMap[startMatcherId] = startMatcherIndex;
1473     atomTrackerMap[stopMatcherId] = stopMatcherIndex;
1474     atomTrackerMap[stopAllMatcherId] = stopAllMatcherIndex;
1475 
1476     optional<InvalidConfigReason> invalidConfigReason;
1477     sp<ConditionTracker> tracker =
1478             createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1479     EXPECT_EQ(invalidConfigReason, nullopt);
1480     EXPECT_EQ(tracker->getConditionId(), id);
1481     EXPECT_EQ(tracker->isSliced(), false);
1482     EXPECT_TRUE(tracker->IsSimpleCondition());
1483     const set<int>& interestedMatchers = tracker->getAtomMatchingTrackerIndex();
1484     ASSERT_EQ(interestedMatchers.size(), 3);
1485     ASSERT_EQ(interestedMatchers.count(startMatcherIndex), 1);
1486     ASSERT_EQ(interestedMatchers.count(stopMatcherIndex), 1);
1487     ASSERT_EQ(interestedMatchers.count(stopAllMatcherIndex), 1);
1488 }
1489 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerCombination)1490 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerCombination) {
1491     int index = 1;
1492     int64_t id = 987;
1493     const ConfigKey key(123, 456);
1494 
1495     Predicate predicate;
1496     predicate.set_id(id);
1497     Predicate_Combination* combinationPredicate = predicate.mutable_combination();
1498     combinationPredicate->set_operation(LogicalOperation::AND);
1499     combinationPredicate->add_predicate(888);
1500     combinationPredicate->add_predicate(777);
1501 
1502     // Combination conditions must be initialized to set most state.
1503     unordered_map<int64_t, int> atomTrackerMap;
1504     optional<InvalidConfigReason> invalidConfigReason;
1505     sp<ConditionTracker> tracker =
1506             createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1507     EXPECT_EQ(invalidConfigReason, nullopt);
1508     EXPECT_EQ(tracker->getConditionId(), id);
1509     EXPECT_FALSE(tracker->IsSimpleCondition());
1510 }
1511 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerInvalidMetric)1512 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerInvalidMetric) {
1513     Alert alert;
1514     alert.set_id(123);
1515     alert.set_metric_id(1);
1516     alert.set_trigger_if_sum_gt(1);
1517     alert.set_num_buckets(1);
1518 
1519     sp<AlarmMonitor> anomalyAlarmMonitor;
1520     vector<sp<MetricProducer>> metricProducers;
1521     optional<InvalidConfigReason> invalidConfigReason;
1522     // Pass in empty metric producers, causing an error.
1523     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123, {},
1524                                    metricProducers, invalidConfigReason),
1525               nullopt);
1526     EXPECT_EQ(invalidConfigReason,
1527               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
1528                                                  alert.metric_id(), alert.id()));
1529 }
1530 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerNoThreshold)1531 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerNoThreshold) {
1532     int64_t metricId = 1;
1533     Alert alert;
1534     alert.set_id(123);
1535     alert.set_metric_id(metricId);
1536     alert.set_num_buckets(1);
1537 
1538     CountMetric metric;
1539     metric.set_id(metricId);
1540     metric.set_bucket(ONE_MINUTE);
1541     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1542     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1543     vector<sp<MetricProducer>> metricProducers(
1544             {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1545                                      0x0123456789, 0, 0, provider)});
1546     sp<AlarmMonitor> anomalyAlarmMonitor;
1547     optional<InvalidConfigReason> invalidConfigReason;
1548     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1549                                    {{1, 0}}, metricProducers, invalidConfigReason),
1550               nullopt);
1551     EXPECT_EQ(invalidConfigReason,
1552               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_THRESHOLD_MISSING,
1553                                                  alert.id()));
1554 }
1555 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerMissingBuckets)1556 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerMissingBuckets) {
1557     int64_t metricId = 1;
1558     Alert alert;
1559     alert.set_id(123);
1560     alert.set_metric_id(metricId);
1561     alert.set_trigger_if_sum_gt(1);
1562 
1563     CountMetric metric;
1564     metric.set_id(metricId);
1565     metric.set_bucket(ONE_MINUTE);
1566     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1567     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1568     vector<sp<MetricProducer>> metricProducers(
1569             {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1570                                      0x0123456789, 0, 0, provider)});
1571     sp<AlarmMonitor> anomalyAlarmMonitor;
1572     optional<InvalidConfigReason> invalidConfigReason;
1573     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1574                                    {{1, 0}}, metricProducers, invalidConfigReason),
1575               nullopt);
1576     EXPECT_EQ(invalidConfigReason,
1577               createInvalidConfigReasonWithAlert(
1578                       INVALID_CONFIG_REASON_ALERT_INVALID_TRIGGER_OR_NUM_BUCKETS, alert.id()));
1579 }
1580 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerGood)1581 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerGood) {
1582     int64_t metricId = 1;
1583     Alert alert;
1584     alert.set_id(123);
1585     alert.set_metric_id(metricId);
1586     alert.set_trigger_if_sum_gt(1);
1587     alert.set_num_buckets(1);
1588 
1589     CountMetric metric;
1590     metric.set_id(metricId);
1591     metric.set_bucket(ONE_MINUTE);
1592     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1593     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1594     vector<sp<MetricProducer>> metricProducers(
1595             {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1596                                      0x0123456789, 0, 0, provider)});
1597     sp<AlarmMonitor> anomalyAlarmMonitor;
1598     optional<InvalidConfigReason> invalidConfigReason;
1599     EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1600                                    {{1, 0}}, metricProducers, invalidConfigReason),
1601               nullopt);
1602     EXPECT_EQ(invalidConfigReason, nullopt);
1603 }
1604 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerDurationTooLong)1605 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerDurationTooLong) {
1606     int64_t metricId = 1;
1607     Alert alert;
1608     alert.set_id(123);
1609     alert.set_metric_id(metricId);
1610     // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
1611     alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
1612     alert.set_num_buckets(1);
1613 
1614     DurationMetric metric;
1615     metric.set_id(metricId);
1616     metric.set_bucket(ONE_MINUTE);
1617     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
1618     FieldMatcher dimensions;
1619     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1620     sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1621     vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
1622             kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
1623             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
1624             wizard, 0x0123456789, dimensions, 0, 0, provider)});
1625     sp<AlarmMonitor> anomalyAlarmMonitor;
1626     optional<InvalidConfigReason> invalidConfigReason;
1627     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1628                                    {{1, 0}}, metricProducers, invalidConfigReason),
1629               nullopt);
1630     EXPECT_EQ(invalidConfigReason,
1631               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_CANNOT_ADD_ANOMALY,
1632                                                  alert.metric_id(), alert.id()));
1633 }
1634 
TEST_F(MetricsManagerUtilTest,TestCreateDurationProducerDimensionsInWhatInvalid)1635 TEST_F(MetricsManagerUtilTest, TestCreateDurationProducerDimensionsInWhatInvalid) {
1636     StatsdConfig config;
1637     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1638     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1639     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
1640     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
1641 
1642     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1643     // The predicate is dimensioning by first attribution node by uid.
1644     FieldMatcher dimensions =
1645             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1646     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
1647     *config.add_predicate() = holdingWakelockPredicate;
1648 
1649     DurationMetric* durationMetric = config.add_duration_metric();
1650     durationMetric->set_id(StringToId("WakelockDuration"));
1651     durationMetric->set_what(holdingWakelockPredicate.id());
1652     durationMetric->set_aggregation_type(DurationMetric::SUM);
1653     // The metric is dimensioning by first attribution node by uid AND tag.
1654     // Invalid since the predicate only dimensions by uid.
1655     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
1656             util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
1657     durationMetric->set_bucket(FIVE_MINUTES);
1658 
1659     ConfigKey key(123, 987);
1660     uint64_t timeNs = 456;
1661     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1662     sp<AlarmMonitor> anomalyAlarmMonitor;
1663     sp<AlarmMonitor> periodicAlarmMonitor;
1664     sp<UidMap> uidMap;
1665     sp<MetricsManager> metricsManager =
1666             new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1667                                anomalyAlarmMonitor, periodicAlarmMonitor);
1668     EXPECT_FALSE(metricsManager->isConfigValid());
1669 }
1670 
TEST_F(MetricsManagerUtilTest,TestSampledMetrics)1671 TEST_F(MetricsManagerUtilTest, TestSampledMetrics) {
1672     StatsdConfig config;
1673 
1674     AtomMatcher appCrashMatcher =
1675             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1676     *config.add_atom_matcher() = appCrashMatcher;
1677 
1678     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1679     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1680 
1681     AtomMatcher bleScanResultReceivedMatcher = CreateSimpleAtomMatcher(
1682             "BleScanResultReceivedAtomMatcher", util::BLE_SCAN_RESULT_RECEIVED);
1683     *config.add_atom_matcher() = bleScanResultReceivedMatcher;
1684 
1685     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1686     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
1687             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1688     *config.add_predicate() = holdingWakelockPredicate;
1689 
1690     CountMetric sampledCountMetric =
1691             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1692     *sampledCountMetric.mutable_dimensions_in_what() =
1693             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1694     *sampledCountMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1695             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1696     sampledCountMetric.mutable_dimensional_sampling_info()->set_shard_count(2);
1697     *config.add_count_metric() = sampledCountMetric;
1698 
1699     CountMetric unsampledCountMetric =
1700             createCountMetric("CountAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1701     *unsampledCountMetric.mutable_dimensions_in_what() =
1702             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1703     *config.add_count_metric() = unsampledCountMetric;
1704 
1705     DurationMetric sampledDurationMetric = createDurationMetric(
1706             "DurationSampledWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1707     *sampledDurationMetric.mutable_dimensions_in_what() =
1708             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1709     *sampledDurationMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1710             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1711     sampledDurationMetric.mutable_dimensional_sampling_info()->set_shard_count(4);
1712     *config.add_duration_metric() = sampledDurationMetric;
1713 
1714     DurationMetric unsampledDurationMetric = createDurationMetric(
1715             "DurationWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1716     unsampledDurationMetric.set_aggregation_type(DurationMetric::SUM);
1717     *unsampledDurationMetric.mutable_dimensions_in_what() =
1718             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1719     *config.add_duration_metric() = unsampledDurationMetric;
1720 
1721     ValueMetric sampledValueMetric =
1722             createValueMetric("ValueSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1723                               /*num_results=*/2, nullopt, {});
1724     *sampledValueMetric.mutable_dimensions_in_what() =
1725             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1726     *sampledValueMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1727             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1728     sampledValueMetric.mutable_dimensional_sampling_info()->set_shard_count(6);
1729     *config.add_value_metric() = sampledValueMetric;
1730 
1731     ValueMetric unsampledValueMetric =
1732             createValueMetric("ValueBleScanResultsPerUid", bleScanResultReceivedMatcher,
1733                               /*num_results=*/2, nullopt, {});
1734     *unsampledValueMetric.mutable_dimensions_in_what() =
1735             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1736     *config.add_value_metric() = unsampledValueMetric;
1737 
1738     KllMetric sampledKllMetric =
1739             createKllMetric("KllSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1740                             /*num_results=*/2, nullopt);
1741     *sampledKllMetric.mutable_dimensions_in_what() =
1742             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1743     *sampledKllMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1744             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1745     sampledKllMetric.mutable_dimensional_sampling_info()->set_shard_count(8);
1746     *config.add_kll_metric() = sampledKllMetric;
1747 
1748     KllMetric unsampledKllMetric = createKllMetric(
1749             "KllBleScanResultsPerUid", bleScanResultReceivedMatcher, /*num_results=*/2, nullopt);
1750     *unsampledKllMetric.mutable_dimensions_in_what() =
1751             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1752     *config.add_kll_metric() = unsampledKllMetric;
1753 
1754     GaugeMetric sampledGaugeMetric =
1755             createGaugeMetric("GaugeSampledAppCrashesPerUid", appCrashMatcher.id(),
1756                               GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1757     *sampledGaugeMetric.mutable_dimensions_in_what() =
1758             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1759     *sampledGaugeMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1760             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1761     sampledGaugeMetric.mutable_dimensional_sampling_info()->set_shard_count(10);
1762     *config.add_gauge_metric() = sampledGaugeMetric;
1763 
1764     GaugeMetric unsampledGaugeMetric =
1765             createGaugeMetric("GaugeAppCrashesPerUid", appCrashMatcher.id(),
1766                               GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1767     *unsampledGaugeMetric.mutable_dimensions_in_what() =
1768             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1769     *config.add_gauge_metric() = unsampledGaugeMetric;
1770 
1771     ConfigKey key(123, 987);
1772     uint64_t timeNs = 456;
1773     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1774     sp<AlarmMonitor> anomalyAlarmMonitor;
1775     sp<AlarmMonitor> periodicAlarmMonitor;
1776     sp<UidMap> uidMap;
1777     sp<MetricsManager> metricsManager =
1778             new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1779                                anomalyAlarmMonitor, periodicAlarmMonitor);
1780     ASSERT_TRUE(metricsManager->isConfigValid());
1781     ASSERT_EQ(10, metricsManager->mAllMetricProducers.size());
1782 
1783     sp<MetricProducer> sampledCountMetricProducer = metricsManager->mAllMetricProducers[0];
1784     sp<MetricProducer> unsampledCountMetricProducer = metricsManager->mAllMetricProducers[1];
1785     sp<MetricProducer> sampledDurationMetricProducer = metricsManager->mAllMetricProducers[2];
1786     sp<MetricProducer> unsampledDurationMetricProducer = metricsManager->mAllMetricProducers[3];
1787     sp<MetricProducer> sampledValueMetricProducer = metricsManager->mAllMetricProducers[4];
1788     sp<MetricProducer> unsampledValueMetricProducer = metricsManager->mAllMetricProducers[5];
1789     sp<MetricProducer> sampledKllMetricProducer = metricsManager->mAllMetricProducers[6];
1790     sp<MetricProducer> unsampledKllMetricProducer = metricsManager->mAllMetricProducers[7];
1791     sp<MetricProducer> sampledGaugeMetricProducer = metricsManager->mAllMetricProducers[8];
1792     sp<MetricProducer> unsampledGaugeMetricProducer = metricsManager->mAllMetricProducers[9];
1793 
1794     // Check shard count is set correctly for sampled metrics or set to default.
1795     EXPECT_EQ(2, sampledCountMetricProducer->mShardCount);
1796     EXPECT_EQ(0, unsampledCountMetricProducer->mShardCount);
1797     EXPECT_EQ(4, sampledDurationMetricProducer->mShardCount);
1798     EXPECT_EQ(0, unsampledDurationMetricProducer->mShardCount);
1799     EXPECT_EQ(6, sampledValueMetricProducer->mShardCount);
1800     EXPECT_EQ(0, unsampledValueMetricProducer->mShardCount);
1801     EXPECT_EQ(8, sampledKllMetricProducer->mShardCount);
1802     EXPECT_EQ(0, unsampledKllMetricProducer->mShardCount);
1803     EXPECT_EQ(10, sampledGaugeMetricProducer->mShardCount);
1804     EXPECT_EQ(0, unsampledGaugeMetricProducer->mShardCount);
1805 
1806     // Check sampled what fields is set correctly or empty.
1807     EXPECT_EQ(1, sampledCountMetricProducer->mSampledWhatFields.size());
1808     EXPECT_EQ(true, unsampledCountMetricProducer->mSampledWhatFields.empty());
1809     EXPECT_EQ(1, sampledDurationMetricProducer->mSampledWhatFields.size());
1810     EXPECT_EQ(true, unsampledDurationMetricProducer->mSampledWhatFields.empty());
1811     EXPECT_EQ(1, sampledValueMetricProducer->mSampledWhatFields.size());
1812     EXPECT_EQ(true, unsampledValueMetricProducer->mSampledWhatFields.empty());
1813     EXPECT_EQ(1, sampledKllMetricProducer->mSampledWhatFields.size());
1814     EXPECT_EQ(true, unsampledKllMetricProducer->mSampledWhatFields.empty());
1815     EXPECT_EQ(1, sampledGaugeMetricProducer->mSampledWhatFields.size());
1816     EXPECT_EQ(true, unsampledGaugeMetricProducer->mSampledWhatFields.empty());
1817 }
1818 
TEST_F(MetricsManagerUtilTest,TestMetricHasShardCountButNoSampledField)1819 TEST_F(MetricsManagerUtilTest, TestMetricHasShardCountButNoSampledField) {
1820     AtomMatcher appCrashMatcher =
1821             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1822 
1823     StatsdConfig config;
1824     *config.add_atom_matcher() = appCrashMatcher;
1825 
1826     CountMetric metric =
1827             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1828     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1829     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1830     *config.add_count_metric() = metric;
1831 
1832     EXPECT_EQ(initConfig(config),
1833               InvalidConfigReason(
1834                       INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_MISSING_SAMPLED_FIELD,
1835                       metric.id()));
1836 }
1837 
TEST_F(MetricsManagerUtilTest,TestMetricHasSampledFieldIncorrectShardCount)1838 TEST_F(MetricsManagerUtilTest, TestMetricHasSampledFieldIncorrectShardCount) {
1839     AtomMatcher appCrashMatcher =
1840             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1841 
1842     StatsdConfig config;
1843     *config.add_atom_matcher() = appCrashMatcher;
1844 
1845     CountMetric metric =
1846             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1847     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1848     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1849             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1850     *config.add_count_metric() = metric;
1851 
1852     EXPECT_EQ(initConfig(config),
1853               InvalidConfigReason(
1854                       INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_INCORRECT_SHARD_COUNT,
1855                       metric.id()));
1856 }
1857 
TEST_F(MetricsManagerUtilTest,TestMetricHasMultipleSampledFields)1858 TEST_F(MetricsManagerUtilTest, TestMetricHasMultipleSampledFields) {
1859     AtomMatcher appCrashMatcher =
1860             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1861 
1862     StatsdConfig config;
1863     *config.add_atom_matcher() = appCrashMatcher;
1864 
1865     CountMetric metric =
1866             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1867     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1868     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1869             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/, 2 /*event_type*/});
1870     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1871     *config.add_count_metric() = metric;
1872 
1873     EXPECT_EQ(initConfig(config),
1874               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1875                                   metric.id()));
1876 }
1877 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionALL)1878 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionALL) {
1879     AtomMatcher testAtomReportedMatcher =
1880             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1881 
1882     StatsdConfig config;
1883     *config.add_atom_matcher() = testAtomReportedMatcher;
1884 
1885     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1886                                            testAtomReportedMatcher.id(), nullopt, {});
1887     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1888             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
1889     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1890             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1891                                      {Position::ALL});
1892     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1893     *config.add_count_metric() = metric;
1894 
1895     EXPECT_EQ(initConfig(config),
1896               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1897                                   metric.id()));
1898 }
1899 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionANY)1900 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionANY) {
1901     AtomMatcher testAtomReportedMatcher =
1902             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1903 
1904     StatsdConfig config;
1905     *config.add_atom_matcher() = testAtomReportedMatcher;
1906 
1907     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1908                                            testAtomReportedMatcher.id(), nullopt, {});
1909     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1910             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ANY});
1911     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1912             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1913                                      {Position::ALL});
1914     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1915     *config.add_count_metric() = metric;
1916 
1917     EXPECT_EQ(initConfig(config),
1918               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1919                                   metric.id()));
1920 }
1921 
TEST_F(MetricsManagerUtilTest,TestMetricSampledField_DifferentFieldsNotSubsetDimension)1922 TEST_F(MetricsManagerUtilTest, TestMetricSampledField_DifferentFieldsNotSubsetDimension) {
1923     AtomMatcher appCrashMatcher =
1924             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1925 
1926     StatsdConfig config;
1927     *config.add_atom_matcher() = appCrashMatcher;
1928 
1929     CountMetric metric =
1930             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1931     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1932             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1933     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1934     *config.add_count_metric() = metric;
1935 
1936     EXPECT_EQ(
1937             initConfig(config),
1938             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1939                                 metric.id()));
1940 }
1941 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastNotSubsetDimensionsFirst)1942 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastNotSubsetDimensionsFirst) {
1943     AtomMatcher testAtomReportedMatcher =
1944             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1945 
1946     StatsdConfig config;
1947     *config.add_atom_matcher() = testAtomReportedMatcher;
1948 
1949     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1950                                            testAtomReportedMatcher.id(), nullopt, {});
1951     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1952             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::FIRST});
1953     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1954             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1955                                      {Position::LAST});
1956     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1957     *config.add_count_metric() = metric;
1958 
1959     EXPECT_EQ(
1960             initConfig(config),
1961             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1962                                 metric.id()));
1963 }
1964 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstNotSubsetDimensionsLast)1965 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstNotSubsetDimensionsLast) {
1966     AtomMatcher testAtomReportedMatcher =
1967             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1968 
1969     StatsdConfig config;
1970     *config.add_atom_matcher() = testAtomReportedMatcher;
1971 
1972     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1973                                            testAtomReportedMatcher.id(), nullopt, {});
1974     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1975             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::LAST});
1976     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1977             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1978                                      {Position::FIRST});
1979     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1980     *config.add_count_metric() = metric;
1981 
1982     EXPECT_EQ(
1983             initConfig(config),
1984             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1985                                 metric.id()));
1986 }
1987 
1988 // dimensions_in_what position ALL, sampled_what_field position FIRST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstSubsetDimensionsAll)1989 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstSubsetDimensionsAll) {
1990     AtomMatcher testAtomReportedMatcher =
1991             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1992 
1993     StatsdConfig config;
1994     *config.add_atom_matcher() = testAtomReportedMatcher;
1995 
1996     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1997                                            testAtomReportedMatcher.id(), nullopt, {});
1998     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1999             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
2000     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
2001             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
2002                                      {Position::FIRST});
2003     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
2004     *config.add_count_metric() = metric;
2005     EXPECT_EQ(initConfig(config), nullopt);
2006 }
2007 
2008 // dimensions_in_what position ALL, sampled_what_field position LAST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastSubsetDimensionsAll)2009 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastSubsetDimensionsAll) {
2010     AtomMatcher testAtomReportedMatcher =
2011             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
2012 
2013     StatsdConfig config;
2014     *config.add_atom_matcher() = testAtomReportedMatcher;
2015 
2016     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
2017                                            testAtomReportedMatcher.id(), nullopt, {});
2018     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
2019             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
2020     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
2021             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
2022                                      {Position::LAST});
2023     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
2024     *config.add_count_metric() = metric;
2025     EXPECT_EQ(initConfig(config), nullopt);
2026 }
2027 
2028 // dimensions_in_what position FIRST, sampled_what_field position FIRST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstSubsetDimensionsFirst)2029 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstSubsetDimensionsFirst) {
2030     AtomMatcher testAtomReportedMatcher =
2031             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
2032 
2033     StatsdConfig config;
2034     *config.add_atom_matcher() = testAtomReportedMatcher;
2035 
2036     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
2037                                            testAtomReportedMatcher.id(), nullopt, {});
2038     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
2039             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::FIRST});
2040     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
2041             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
2042                                      {Position::FIRST});
2043     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
2044     *config.add_count_metric() = metric;
2045     EXPECT_EQ(initConfig(config), nullopt);
2046 }
2047 
2048 // dimensions_in_what position LAST, sampled_what_field position LAST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastSubsetDimensionsLast)2049 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastSubsetDimensionsLast) {
2050     AtomMatcher testAtomReportedMatcher =
2051             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
2052 
2053     StatsdConfig config;
2054     *config.add_atom_matcher() = testAtomReportedMatcher;
2055 
2056     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
2057                                            testAtomReportedMatcher.id(), nullopt, {});
2058     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
2059             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::LAST});
2060     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
2061             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
2062                                      {Position::LAST});
2063     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
2064     *config.add_count_metric() = metric;
2065     EXPECT_EQ(initConfig(config), nullopt);
2066 }
2067 
TEST_F(MetricsManagerUtilTest,TestCountMetricHasRestrictedDelegate)2068 TEST_F(MetricsManagerUtilTest, TestCountMetricHasRestrictedDelegate) {
2069     StatsdConfig config;
2070     CountMetric* metric = config.add_count_metric();
2071     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2072 
2073     EXPECT_EQ(initConfig(config),
2074               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2075 }
2076 
TEST_F(MetricsManagerUtilTest,TestDurationMetricHasRestrictedDelegate)2077 TEST_F(MetricsManagerUtilTest, TestDurationMetricHasRestrictedDelegate) {
2078     StatsdConfig config;
2079     DurationMetric* metric = config.add_duration_metric();
2080     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2081 
2082     EXPECT_EQ(initConfig(config),
2083               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2084 }
2085 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricHasRestrictedDelegate)2086 TEST_F(MetricsManagerUtilTest, TestGaugeMetricHasRestrictedDelegate) {
2087     StatsdConfig config;
2088     GaugeMetric* metric = config.add_gauge_metric();
2089     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2090 
2091     EXPECT_EQ(initConfig(config),
2092               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2093 }
2094 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHasRestrictedDelegate)2095 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHasRestrictedDelegate) {
2096     StatsdConfig config;
2097     ValueMetric* metric = config.add_value_metric();
2098     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2099 
2100     EXPECT_EQ(initConfig(config),
2101               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2102 }
2103 
TEST_F(MetricsManagerUtilTest,TestKllMetricHasRestrictedDelegate)2104 TEST_F(MetricsManagerUtilTest, TestKllMetricHasRestrictedDelegate) {
2105     StatsdConfig config;
2106     KllMetric* metric = config.add_kll_metric();
2107     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2108 
2109     EXPECT_EQ(initConfig(config),
2110               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2111 }
2112 
TEST_P(MetricsManagerUtilDimLimitTest,TestDimLimit)2113 TEST_P(MetricsManagerUtilDimLimitTest, TestDimLimit) {
2114     StatsdConfig config = buildGoodConfig(kConfigId, kAlertId);
2115     const auto& [configLimit, actualLimit] = GetParam();
2116     if (configLimit > 0) {
2117         config.mutable_count_metric(0)->set_max_dimensions_per_bucket(configLimit);
2118         config.mutable_duration_metric(0)->set_max_dimensions_per_bucket(configLimit);
2119         config.mutable_gauge_metric(0)->set_max_dimensions_per_bucket(configLimit);
2120         config.mutable_value_metric(0)->set_max_dimensions_per_bucket(configLimit);
2121         config.mutable_kll_metric(0)->set_max_dimensions_per_bucket(configLimit);
2122     }
2123 
2124     // initConfig returns nullopt if config is valid
2125     EXPECT_EQ(initConfig(config), nullopt);
2126     ASSERT_EQ(5u, allMetricProducers.size());
2127 
2128     sp<MetricProducer> producer =
2129             allMetricProducers[metricProducerMap.at(config.count_metric(0).id())];
2130     CountMetricProducer* countProducer = static_cast<CountMetricProducer*>(producer.get());
2131     EXPECT_EQ(countProducer->mDimensionHardLimit, actualLimit);
2132 
2133     producer = allMetricProducers[metricProducerMap.at(config.duration_metric(0).id())];
2134     DurationMetricProducer* durationProducer = static_cast<DurationMetricProducer*>(producer.get());
2135     EXPECT_EQ(durationProducer->mDimensionHardLimit, actualLimit);
2136 
2137     producer = allMetricProducers[metricProducerMap.at(config.gauge_metric(0).id())];
2138     GaugeMetricProducer* gaugeProducer = static_cast<GaugeMetricProducer*>(producer.get());
2139     EXPECT_EQ(gaugeProducer->mDimensionHardLimit, actualLimit);
2140 
2141     producer = allMetricProducers[metricProducerMap.at(config.value_metric(0).id())];
2142     NumericValueMetricProducer* numericValueProducer =
2143             static_cast<NumericValueMetricProducer*>(producer.get());
2144     EXPECT_EQ(numericValueProducer->mDimensionHardLimit, actualLimit);
2145 
2146     producer = allMetricProducers[metricProducerMap.at(config.kll_metric(0).id())];
2147     KllMetricProducer* kllProducer = static_cast<KllMetricProducer*>(producer.get());
2148     EXPECT_EQ(kllProducer->mDimensionHardLimit, actualLimit);
2149 }
2150 
TEST_F(MetricsManagerUtilTest,TestMissingValueMatcherAndStringReplacer)2151 TEST_F(MetricsManagerUtilTest, TestMissingValueMatcherAndStringReplacer) {
2152     StatsdConfig config;
2153     config.set_id(12345);
2154 
2155     AtomMatcher* matcher = config.add_atom_matcher();
2156     matcher->set_id(111);
2157     matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2158     matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2159 
2160     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2161 
2162     ASSERT_NE(actualInvalidConfigReason, nullopt);
2163     EXPECT_EQ(actualInvalidConfigReason->reason,
2164               INVALID_CONFIG_REASON_MATCHER_NO_VALUE_MATCHER_NOR_STRING_REPLACER);
2165     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2166 }
2167 
TEST_F(MetricsManagerUtilTest,TestMatcherWithValueMatcherOnly)2168 TEST_F(MetricsManagerUtilTest, TestMatcherWithValueMatcherOnly) {
2169     StatsdConfig config;
2170     config.set_id(12345);
2171 
2172     AtomMatcher* matcher = config.add_atom_matcher();
2173     matcher->set_id(111);
2174     matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2175     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2176     fvm->set_field(2 /*int_field*/);
2177     fvm->set_eq_int(1);
2178 
2179     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2180 
2181     ASSERT_EQ(actualInvalidConfigReason, nullopt);
2182 }
2183 
TEST_F(MetricsManagerUtilTest,TestMatcherWithStringReplacerOnly)2184 TEST_F(MetricsManagerUtilTest, TestMatcherWithStringReplacerOnly) {
2185     StatsdConfig config;
2186     config.set_id(12345);
2187 
2188     AtomMatcher* matcher = config.add_atom_matcher();
2189     matcher->set_id(111);
2190     matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2191     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2192     fvm->set_field(5 /*string_field*/);
2193     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2194     fvm->mutable_replace_string()->set_replacement("#");
2195 
2196     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2197 
2198     ASSERT_EQ(actualInvalidConfigReason, nullopt);
2199 }
2200 
TEST_F(MetricsManagerUtilTest,TestValueMatcherWithPositionAll)2201 TEST_F(MetricsManagerUtilTest, TestValueMatcherWithPositionAll) {
2202     StatsdConfig config;
2203     config.set_id(12345);
2204 
2205     AtomMatcher* matcher = config.add_atom_matcher();
2206     matcher->set_id(111);
2207     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2208     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2209     fvm->set_field(9 /*repeated_int_field*/);
2210     fvm->set_position(Position::ALL);
2211     fvm->set_eq_int(1);
2212 
2213     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2214 
2215     ASSERT_NE(actualInvalidConfigReason, nullopt);
2216     EXPECT_EQ(actualInvalidConfigReason->reason,
2217               INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2218     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2219 }
2220 
TEST_F(MetricsManagerUtilTest,TestValueMatcherAndStringReplaceWithPositionAll)2221 TEST_F(MetricsManagerUtilTest, TestValueMatcherAndStringReplaceWithPositionAll) {
2222     StatsdConfig config;
2223     config.set_id(12345);
2224 
2225     AtomMatcher* matcher = config.add_atom_matcher();
2226     matcher->set_id(111);
2227     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2228     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2229     fvm->set_field(12 /*repeated_string_field*/);
2230     fvm->set_position(Position::ALL);
2231     fvm->set_eq_string("foo");
2232     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2233     fvm->mutable_replace_string()->set_replacement("");
2234 
2235     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2236 
2237     ASSERT_NE(actualInvalidConfigReason, nullopt);
2238     EXPECT_EQ(actualInvalidConfigReason->reason,
2239               INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2240     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2241 }
2242 
TEST_F(MetricsManagerUtilTest,TestValueMatcherWithPositionAllNested)2243 TEST_F(MetricsManagerUtilTest, TestValueMatcherWithPositionAllNested) {
2244     StatsdConfig config;
2245     config.set_id(12345);
2246 
2247     // Match on attribution_node[ALL].uid = 1
2248     AtomMatcher* matcher = config.add_atom_matcher();
2249     matcher->set_id(111);
2250     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2251     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2252     fvm->set_field(1 /*attribution_node*/);
2253     fvm->set_position(Position::ALL);
2254     fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(1 /* uid */);
2255     fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_int(1);
2256 
2257     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2258 
2259     ASSERT_NE(actualInvalidConfigReason, nullopt);
2260     EXPECT_EQ(actualInvalidConfigReason->reason,
2261               INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2262     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2263 }
2264 
TEST_F(MetricsManagerUtilTest,TestValueMatcherAndStringReplaceWithPositionAllNested)2265 TEST_F(MetricsManagerUtilTest, TestValueMatcherAndStringReplaceWithPositionAllNested) {
2266     StatsdConfig config;
2267     config.set_id(12345);
2268 
2269     // Match on attribution_node[ALL].uid = 1
2270     AtomMatcher* matcher = config.add_atom_matcher();
2271     matcher->set_id(111);
2272     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2273     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2274     fvm->set_field(1 /*attribution_node*/);
2275     fvm->set_position(Position::ALL);
2276     fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2277     fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("foo");
2278     fvm->mutable_matches_tuple()
2279             ->mutable_field_value_matcher(0)
2280             ->mutable_replace_string()
2281             ->set_regex(R"([0-9]+$)");
2282     fvm->mutable_matches_tuple()
2283             ->mutable_field_value_matcher(0)
2284             ->mutable_replace_string()
2285             ->set_replacement("");
2286 
2287     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2288 
2289     ASSERT_NE(actualInvalidConfigReason, nullopt);
2290     EXPECT_EQ(actualInvalidConfigReason->reason,
2291               INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2292     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2293 }
2294 
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithNoValueMatcherWithPositionAny)2295 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithNoValueMatcherWithPositionAny) {
2296     StatsdConfig config;
2297     config.set_id(12345);
2298 
2299     AtomMatcher* matcher = config.add_atom_matcher();
2300     matcher->set_id(111);
2301     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2302     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2303     fvm->set_field(12 /*repeated_string_field*/);
2304     fvm->set_position(Position::ANY);
2305     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2306     fvm->mutable_replace_string()->set_replacement("");
2307 
2308     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2309 
2310     ASSERT_NE(actualInvalidConfigReason, nullopt);
2311     EXPECT_EQ(actualInvalidConfigReason->reason,
2312               INVALID_CONFIG_REASON_MATCHER_STRING_REPLACE_WITH_NO_VALUE_MATCHER_WITH_POSITION_ANY);
2313     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2314 }
2315 
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithNoValueMatcherWithPositionAnyNested)2316 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithNoValueMatcherWithPositionAnyNested) {
2317     StatsdConfig config;
2318     config.set_id(12345);
2319 
2320     // Match on attribution_node[ALL].uid = 1
2321     AtomMatcher* matcher = config.add_atom_matcher();
2322     matcher->set_id(111);
2323     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2324     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2325     fvm->set_field(1 /*attribution_node*/);
2326     fvm->set_position(Position::ANY);
2327     fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2328     fvm->mutable_matches_tuple()
2329             ->mutable_field_value_matcher(0)
2330             ->mutable_replace_string()
2331             ->set_regex(R"([0-9]+$)");
2332     fvm->mutable_matches_tuple()
2333             ->mutable_field_value_matcher(0)
2334             ->mutable_replace_string()
2335             ->set_replacement("");
2336 
2337     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2338 
2339     ASSERT_NE(actualInvalidConfigReason, nullopt);
2340     EXPECT_EQ(actualInvalidConfigReason->reason,
2341               INVALID_CONFIG_REASON_MATCHER_STRING_REPLACE_WITH_NO_VALUE_MATCHER_WITH_POSITION_ANY);
2342     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2343 }
2344 
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithValueMatcherWithPositionAny)2345 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithValueMatcherWithPositionAny) {
2346     StatsdConfig config;
2347     config.set_id(12345);
2348 
2349     AtomMatcher* matcher = config.add_atom_matcher();
2350     matcher->set_id(111);
2351     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2352     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2353     fvm->set_field(12 /*repeated_string_field*/);
2354     fvm->set_position(Position::ANY);
2355     fvm->set_eq_string("bar");
2356     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2357     fvm->mutable_replace_string()->set_replacement("");
2358 
2359     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2360 
2361     ASSERT_EQ(actualInvalidConfigReason, nullopt);
2362 }
2363 
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithValueMatcherWithPositionAnyNested)2364 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithValueMatcherWithPositionAnyNested) {
2365     StatsdConfig config;
2366     config.set_id(12345);
2367 
2368     // Match on attribution_node[ALL].uid = 1
2369     AtomMatcher* matcher = config.add_atom_matcher();
2370     matcher->set_id(111);
2371     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2372     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2373     fvm->set_field(1 /*attribution_node*/);
2374     fvm->set_position(Position::ANY);
2375     fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2376     fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("bar");
2377     fvm->mutable_matches_tuple()
2378             ->mutable_field_value_matcher(0)
2379             ->mutable_replace_string()
2380             ->set_regex(R"([0-9]+$)");
2381     fvm->mutable_matches_tuple()
2382             ->mutable_field_value_matcher(0)
2383             ->mutable_replace_string()
2384             ->set_replacement("");
2385 
2386     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2387 
2388     ASSERT_EQ(actualInvalidConfigReason, nullopt);
2389 }
2390 
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithPositionAllNested)2391 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithPositionAllNested) {
2392     StatsdConfig config;
2393     config.set_id(12345);
2394 
2395     // Replace attribution_node[ALL].tag using "[0-9]+$" -> "".
2396     AtomMatcher* matcher = config.add_atom_matcher();
2397     matcher->set_id(111);
2398     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2399     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2400     fvm->set_field(1 /*attribution_node*/);
2401     fvm->set_position(Position::ALL);
2402     fvm = fvm->mutable_matches_tuple()->add_field_value_matcher();
2403     fvm->set_field(2 /* tag */);
2404     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2405     fvm->mutable_replace_string()->set_replacement("");
2406 
2407     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2408 
2409     ASSERT_EQ(actualInvalidConfigReason, nullopt);
2410 }
2411 
TEST_F(MetricsManagerUtilTest,TestMatcherWithStringReplaceAndNonStringValueMatcher)2412 TEST_F(MetricsManagerUtilTest, TestMatcherWithStringReplaceAndNonStringValueMatcher) {
2413     StatsdConfig config;
2414     config.set_id(12345);
2415 
2416     AtomMatcher* matcher = config.add_atom_matcher();
2417     matcher->set_id(111);
2418     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2419     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2420     fvm->set_field(2 /*int_field*/);
2421     fvm->set_eq_int(1);
2422     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2423     fvm->mutable_replace_string()->set_replacement("#");
2424 
2425     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2426 
2427     ASSERT_NE(actualInvalidConfigReason, nullopt);
2428     EXPECT_EQ(actualInvalidConfigReason->reason,
2429               INVALID_CONFIG_REASON_MATCHER_INVALID_VALUE_MATCHER_WITH_STRING_REPLACE);
2430     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2431 }
2432 
TEST_F(MetricsManagerUtilTest,TestCombinationMatcherWithStringReplace)2433 TEST_F(MetricsManagerUtilTest, TestCombinationMatcherWithStringReplace) {
2434     StatsdConfig config;
2435     config.set_id(12345);
2436 
2437     AtomMatcher* matcher = config.add_atom_matcher();
2438     matcher->set_id(111);
2439     matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2440     FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2441     fvm->set_field(5 /*string_field*/);
2442     fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2443     fvm->mutable_replace_string()->set_replacement("#");
2444 
2445     matcher = config.add_atom_matcher();
2446     matcher->set_id(222);
2447     matcher->mutable_combination()->set_operation(LogicalOperation::NOT);
2448     matcher->mutable_combination()->add_matcher(111);
2449 
2450     optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2451 
2452     ASSERT_NE(actualInvalidConfigReason, nullopt);
2453     EXPECT_EQ(actualInvalidConfigReason->reason,
2454               INVALID_CONFIG_REASON_MATCHER_COMBINATION_WITH_STRING_REPLACE);
2455     EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(222));
2456 }
2457 
2458 }  // namespace statsd
2459 }  // namespace os
2460 }  // namespace android
2461 
2462 #else
2463 GTEST_LOG_(INFO) << "This test does nothing.\n";
2464 #endif
2465