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