• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/metrics/parsing_utils/metrics_manager_util.h"
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <private/android_filesystem_config.h>
20 #include <stdio.h>
21 
22 #include <set>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "src/condition/ConditionTracker.h"
27 #include "src/matchers/AtomMatchingTracker.h"
28 #include "src/metrics/CountMetricProducer.h"
29 #include "src/metrics/DurationMetricProducer.h"
30 #include "src/metrics/GaugeMetricProducer.h"
31 #include "src/metrics/MetricProducer.h"
32 #include "src/metrics/NumericValueMetricProducer.h"
33 #include "src/state/StateManager.h"
34 #include "src/statsd_config.pb.h"
35 #include "tests/metrics/metrics_test_helper.h"
36 #include "tests/statsd_test_util.h"
37 
38 using namespace testing;
39 using android::sp;
40 using android::os::statsd::Predicate;
41 using std::map;
42 using std::set;
43 using std::unordered_map;
44 using std::vector;
45 
46 #ifdef __ANDROID__
47 
48 namespace android {
49 namespace os {
50 namespace statsd {
51 
52 namespace {
53 const ConfigKey kConfigKey(0, 12345);
54 const long timeBaseSec = 1000;
55 const long kAlertId = 3;
56 
57 sp<UidMap> uidMap = new UidMap();
58 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
59 sp<AlarmMonitor> anomalyAlarmMonitor;
60 sp<AlarmMonitor> periodicAlarmMonitor;
61 unordered_map<int, vector<int>> allTagIdsToMatchersMap;
62 vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
63 unordered_map<int64_t, int> atomMatchingTrackerMap;
64 vector<sp<ConditionTracker>> allConditionTrackers;
65 unordered_map<int64_t, int> conditionTrackerMap;
66 vector<sp<MetricProducer>> allMetricProducers;
67 unordered_map<int64_t, int> metricProducerMap;
68 vector<sp<AnomalyTracker>> allAnomalyTrackers;
69 unordered_map<int64_t, int> alertTrackerMap;
70 vector<sp<AlarmTracker>> allAlarmTrackers;
71 unordered_map<int, vector<int>> conditionToMetricMap;
72 unordered_map<int, vector<int>> trackerToMetricMap;
73 unordered_map<int, vector<int>> trackerToConditionMap;
74 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
75 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
76 vector<int> metricsWithActivation;
77 map<int64_t, uint64_t> stateProtoHashes;
78 set<int64_t> noReportMetricIds;
79 
initConfig(const StatsdConfig & config)80 optional<InvalidConfigReason> initConfig(const StatsdConfig& config) {
81     // initStatsdConfig returns nullopt if config is valid
82     return initStatsdConfig(
83             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
84             timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
85             atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
86             metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
87             trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
88             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
89             stateProtoHashes, noReportMetricIds);
90 }
91 
buildGoodConfig()92 StatsdConfig buildGoodConfig() {
93     StatsdConfig config;
94     config.set_id(12345);
95 
96     AtomMatcher* eventMatcher = config.add_atom_matcher();
97     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
98 
99     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
100     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
101     simpleAtomMatcher->add_field_value_matcher()->set_field(
102             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
103     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
104             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
105 
106     eventMatcher = config.add_atom_matcher();
107     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
108 
109     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
110     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
111     simpleAtomMatcher->add_field_value_matcher()->set_field(
112             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
113     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
114             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
115 
116     eventMatcher = config.add_atom_matcher();
117     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
118 
119     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
120     combination->set_operation(LogicalOperation::OR);
121     combination->add_matcher(StringToId("SCREEN_IS_ON"));
122     combination->add_matcher(StringToId("SCREEN_IS_OFF"));
123 
124     CountMetric* metric = config.add_count_metric();
125     metric->set_id(3);
126     metric->set_what(StringToId("SCREEN_IS_ON"));
127     metric->set_bucket(ONE_MINUTE);
128     metric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
129     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
130 
131     config.add_no_report_metric(3);
132 
133     auto alert = config.add_alert();
134     alert->set_id(kAlertId);
135     alert->set_metric_id(3);
136     alert->set_num_buckets(10);
137     alert->set_refractory_period_secs(100);
138     alert->set_trigger_if_sum_gt(100);
139     return config;
140 }
141 
buildCircleMatchers()142 StatsdConfig buildCircleMatchers() {
143     StatsdConfig config;
144     config.set_id(12345);
145 
146     AtomMatcher* eventMatcher = config.add_atom_matcher();
147     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
148 
149     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
150     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
151     simpleAtomMatcher->add_field_value_matcher()->set_field(
152             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
153     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
154             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
155 
156     eventMatcher = config.add_atom_matcher();
157     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
158 
159     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
160     combination->set_operation(LogicalOperation::OR);
161     combination->add_matcher(StringToId("SCREEN_IS_ON"));
162     // Circle dependency
163     combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
164 
165     return config;
166 }
167 
buildAlertWithUnknownMetric()168 StatsdConfig buildAlertWithUnknownMetric() {
169     StatsdConfig config;
170     config.set_id(12345);
171 
172     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
173 
174     CountMetric* metric = config.add_count_metric();
175     metric->set_id(3);
176     metric->set_what(StringToId("ScreenTurnedOn"));
177     metric->set_bucket(ONE_MINUTE);
178     metric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
179     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
180 
181     auto alert = config.add_alert();
182     alert->set_id(3);
183     alert->set_metric_id(2);
184     alert->set_num_buckets(10);
185     alert->set_refractory_period_secs(100);
186     alert->set_trigger_if_sum_gt(100);
187     return config;
188 }
189 
buildMissingMatchers()190 StatsdConfig buildMissingMatchers() {
191     StatsdConfig config;
192     config.set_id(12345);
193 
194     AtomMatcher* eventMatcher = config.add_atom_matcher();
195     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
196 
197     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
198     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
199     simpleAtomMatcher->add_field_value_matcher()->set_field(
200             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
201     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
202             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
203 
204     eventMatcher = config.add_atom_matcher();
205     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
206 
207     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
208     combination->set_operation(LogicalOperation::OR);
209     combination->add_matcher(StringToId("SCREEN_IS_ON"));
210     // undefined matcher
211     combination->add_matcher(StringToId("ABC"));
212 
213     return config;
214 }
215 
buildMissingPredicate()216 StatsdConfig buildMissingPredicate() {
217     StatsdConfig config;
218     config.set_id(12345);
219 
220     CountMetric* metric = config.add_count_metric();
221     metric->set_id(3);
222     metric->set_what(StringToId("SCREEN_EVENT"));
223     metric->set_bucket(ONE_MINUTE);
224     metric->set_condition(StringToId("SOME_CONDITION"));
225 
226     AtomMatcher* eventMatcher = config.add_atom_matcher();
227     eventMatcher->set_id(StringToId("SCREEN_EVENT"));
228 
229     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
230     simpleAtomMatcher->set_atom_id(2);
231 
232     return config;
233 }
234 
buildDimensionMetricsWithMultiTags()235 StatsdConfig buildDimensionMetricsWithMultiTags() {
236     StatsdConfig config;
237     config.set_id(12345);
238 
239     AtomMatcher* eventMatcher = config.add_atom_matcher();
240     eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
241     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
242     simpleAtomMatcher->set_atom_id(2);
243 
244     eventMatcher = config.add_atom_matcher();
245     eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
246     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
247     simpleAtomMatcher->set_atom_id(3);
248 
249     eventMatcher = config.add_atom_matcher();
250     eventMatcher->set_id(StringToId("BATTERY_LOW"));
251 
252     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
253     combination->set_operation(LogicalOperation::OR);
254     combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
255     combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
256 
257     // Count process state changes, slice by uid, while SCREEN_IS_OFF
258     CountMetric* metric = config.add_count_metric();
259     metric->set_id(3);
260     metric->set_what(StringToId("BATTERY_LOW"));
261     metric->set_bucket(ONE_MINUTE);
262     // This case is interesting. We want to dimension across two atoms.
263     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
264 
265     auto alert = config.add_alert();
266     alert->set_id(kAlertId);
267     alert->set_metric_id(3);
268     alert->set_num_buckets(10);
269     alert->set_refractory_period_secs(100);
270     alert->set_trigger_if_sum_gt(100);
271     return config;
272 }
273 
buildCirclePredicates()274 StatsdConfig buildCirclePredicates() {
275     StatsdConfig config;
276     config.set_id(12345);
277 
278     AtomMatcher* eventMatcher = config.add_atom_matcher();
279     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
280 
281     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
282     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
283     simpleAtomMatcher->add_field_value_matcher()->set_field(
284             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
285     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
286             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
287 
288     eventMatcher = config.add_atom_matcher();
289     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
290 
291     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
292     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
293     simpleAtomMatcher->add_field_value_matcher()->set_field(
294             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
295     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
296             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
297 
298     auto condition = config.add_predicate();
299     condition->set_id(StringToId("SCREEN_IS_ON"));
300     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
301     simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
302     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
303 
304     condition = config.add_predicate();
305     condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
306 
307     Predicate_Combination* combination = condition->mutable_combination();
308     combination->set_operation(LogicalOperation::OR);
309     combination->add_predicate(StringToId("SCREEN_IS_ON"));
310     combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
311 
312     return config;
313 }
314 
buildConfigWithDifferentPredicates()315 StatsdConfig buildConfigWithDifferentPredicates() {
316     StatsdConfig config;
317     config.set_id(12345);
318 
319     auto pulledAtomMatcher =
320             CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
321     *config.add_atom_matcher() = pulledAtomMatcher;
322     auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
323     *config.add_atom_matcher() = screenOnAtomMatcher;
324     auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
325     *config.add_atom_matcher() = screenOffAtomMatcher;
326     auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
327     *config.add_atom_matcher() = batteryNoneAtomMatcher;
328     auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
329     *config.add_atom_matcher() = batteryUsbAtomMatcher;
330 
331     // Simple condition with InitialValue set to default (unknown).
332     auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
333     *config.add_predicate() = screenOnUnknownPredicate;
334 
335     // Simple condition with InitialValue set to false.
336     auto screenOnFalsePredicate = config.add_predicate();
337     screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
338     SimplePredicate* simpleScreenOnFalsePredicate =
339             screenOnFalsePredicate->mutable_simple_predicate();
340     simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
341     simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
342     simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
343 
344     // Simple condition with InitialValue set to false.
345     auto onBatteryFalsePredicate = config.add_predicate();
346     onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
347     SimplePredicate* simpleOnBatteryFalsePredicate =
348             onBatteryFalsePredicate->mutable_simple_predicate();
349     simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
350     simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
351     simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
352 
353     // Combination condition with both simple condition InitialValues set to false.
354     auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
355     screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
356     screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
357             LogicalOperation::AND);
358     addPredicateToPredicateCombination(*screenOnFalsePredicate,
359                                        screenOnFalseOnBatteryFalsePredicate);
360     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
361                                        screenOnFalseOnBatteryFalsePredicate);
362 
363     // Combination condition with one simple condition InitialValue set to unknown and one set to
364     // false.
365     auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
366     screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
367     screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
368             LogicalOperation::AND);
369     addPredicateToPredicateCombination(screenOnUnknownPredicate,
370                                        screenOnUnknownOnBatteryFalsePredicate);
371     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
372                                        screenOnUnknownOnBatteryFalsePredicate);
373 
374     // Simple condition metric with initial value false.
375     ValueMetric* metric1 = config.add_value_metric();
376     metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
377     metric1->set_what(pulledAtomMatcher.id());
378     *metric1->mutable_value_field() =
379             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
380     metric1->set_bucket(FIVE_MINUTES);
381     metric1->set_condition(screenOnFalsePredicate->id());
382 
383     // Simple condition metric with initial value unknown.
384     ValueMetric* metric2 = config.add_value_metric();
385     metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
386     metric2->set_what(pulledAtomMatcher.id());
387     *metric2->mutable_value_field() =
388             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
389     metric2->set_bucket(FIVE_MINUTES);
390     metric2->set_condition(screenOnUnknownPredicate.id());
391 
392     // Combination condition metric with initial values false and false.
393     ValueMetric* metric3 = config.add_value_metric();
394     metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
395     metric3->set_what(pulledAtomMatcher.id());
396     *metric3->mutable_value_field() =
397             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
398     metric3->set_bucket(FIVE_MINUTES);
399     metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
400 
401     // Combination condition metric with initial values unknown and false.
402     ValueMetric* metric4 = config.add_value_metric();
403     metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
404     metric4->set_what(pulledAtomMatcher.id());
405     *metric4->mutable_value_field() =
406             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
407     metric4->set_bucket(FIVE_MINUTES);
408     metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
409 
410     return config;
411 }
412 }  // anonymous namespace
413 
414 class MetricsManagerUtilTest : public ::testing::Test {
415 public:
SetUp()416     void SetUp() override {
417         allTagIdsToMatchersMap.clear();
418         allAtomMatchingTrackers.clear();
419         atomMatchingTrackerMap.clear();
420         allConditionTrackers.clear();
421         conditionTrackerMap.clear();
422         allMetricProducers.clear();
423         metricProducerMap.clear();
424         allAnomalyTrackers.clear();
425         allAlarmTrackers.clear();
426         conditionToMetricMap.clear();
427         trackerToMetricMap.clear();
428         trackerToConditionMap.clear();
429         activationAtomTrackerToMetricMap.clear();
430         deactivationAtomTrackerToMetricMap.clear();
431         alertTrackerMap.clear();
432         metricsWithActivation.clear();
433         stateProtoHashes.clear();
434         noReportMetricIds.clear();
435         StateManager::getInstance().clear();
436     }
437 };
438 
TEST_F(MetricsManagerUtilTest,TestInitialConditions)439 TEST_F(MetricsManagerUtilTest, TestInitialConditions) {
440     // initConfig returns nullopt if config is valid
441     EXPECT_EQ(initConfig(buildConfigWithDifferentPredicates()), nullopt);
442     ASSERT_EQ(4u, allMetricProducers.size());
443     ASSERT_EQ(5u, allConditionTrackers.size());
444 
445     ConditionKey queryKey;
446     vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
447 
448     allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
449     allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
450     EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
451     EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
452     EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
453     EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
454     EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
455 
456     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
457     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
458     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
459     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
460 
461     EXPECT_EQ(allTagIdsToMatchersMap.size(), 3);
462     EXPECT_EQ(allTagIdsToMatchersMap[SCREEN_STATE_ATOM_ID].size(), 2);
463     EXPECT_EQ(allTagIdsToMatchersMap[util::PLUGGED_STATE_CHANGED].size(), 2);
464     EXPECT_EQ(allTagIdsToMatchersMap[util::SUBSYSTEM_SLEEP_STATE].size(), 1);
465 }
466 
TEST_F(MetricsManagerUtilTest,TestGoodConfig)467 TEST_F(MetricsManagerUtilTest, TestGoodConfig) {
468     StatsdConfig config = buildGoodConfig();
469     // initConfig returns nullopt if config is valid
470     EXPECT_EQ(initConfig(config), nullopt);
471     ASSERT_EQ(1u, allMetricProducers.size());
472     EXPECT_THAT(metricProducerMap, UnorderedElementsAre(Pair(config.count_metric(0).id(), 0)));
473     ASSERT_EQ(1u, allAnomalyTrackers.size());
474     ASSERT_EQ(1u, noReportMetricIds.size());
475     ASSERT_EQ(1u, alertTrackerMap.size());
476     EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
477     EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
478 }
479 
TEST_F(MetricsManagerUtilTest,TestDimensionMetricsWithMultiTags)480 TEST_F(MetricsManagerUtilTest, TestDimensionMetricsWithMultiTags) {
481     EXPECT_EQ(initConfig(buildDimensionMetricsWithMultiTags()),
482               createInvalidConfigReasonWithMatcher(
483                       INVALID_CONFIG_REASON_METRIC_MATCHER_MORE_THAN_ONE_ATOM, /*metric id=*/3,
484                       StringToId("BATTERY_LOW")));
485 }
486 
TEST_F(MetricsManagerUtilTest,TestCircleLogMatcherDependency)487 TEST_F(MetricsManagerUtilTest, TestCircleLogMatcherDependency) {
488     optional<InvalidConfigReason> expectedInvalidConfigReason =
489             createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CYCLE,
490                                                  StringToId("SCREEN_ON_OR_OFF"));
491     expectedInvalidConfigReason->matcherIds.push_back(StringToId("SCREEN_ON_OR_OFF"));
492 
493     EXPECT_EQ(initConfig(buildCircleMatchers()), expectedInvalidConfigReason);
494 }
495 
TEST_F(MetricsManagerUtilTest,TestMissingMatchers)496 TEST_F(MetricsManagerUtilTest, TestMissingMatchers) {
497     optional<InvalidConfigReason> expectedInvalidConfigReason =
498             createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CHILD_NOT_FOUND,
499                                                  StringToId("SCREEN_ON_OR_OFF"));
500     expectedInvalidConfigReason->matcherIds.push_back(StringToId("ABC"));
501 
502     EXPECT_EQ(initConfig(buildMissingMatchers()), expectedInvalidConfigReason);
503 }
504 
TEST_F(MetricsManagerUtilTest,TestMissingPredicate)505 TEST_F(MetricsManagerUtilTest, TestMissingPredicate) {
506     EXPECT_EQ(
507             initConfig(buildMissingPredicate()),
508             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_METRIC_CONDITION_NOT_FOUND,
509                                                    /*metric id=*/3, StringToId("SOME_CONDITION")));
510 }
511 
TEST_F(MetricsManagerUtilTest,TestCirclePredicateDependency)512 TEST_F(MetricsManagerUtilTest, TestCirclePredicateDependency) {
513     optional<InvalidConfigReason> expectedInvalidConfigReason =
514             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CYCLE,
515                                                    StringToId("SCREEN_IS_EITHER_ON_OFF"));
516     expectedInvalidConfigReason->conditionIds.push_back(StringToId("SCREEN_IS_EITHER_ON_OFF"));
517 
518     EXPECT_EQ(initConfig(buildCirclePredicates()), expectedInvalidConfigReason);
519 }
520 
TEST_F(MetricsManagerUtilTest,TestAlertWithUnknownMetric)521 TEST_F(MetricsManagerUtilTest, TestAlertWithUnknownMetric) {
522     EXPECT_EQ(initConfig(buildAlertWithUnknownMetric()),
523               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
524                                                  /*metric id=*/2, /*matcher id=*/3));
525 }
526 
TEST_F(MetricsManagerUtilTest,TestMetricWithMultipleActivations)527 TEST_F(MetricsManagerUtilTest, TestMetricWithMultipleActivations) {
528     StatsdConfig config;
529     int64_t metricId = 1;
530     auto metric_activation1 = config.add_metric_activation();
531     metric_activation1->set_metric_id(metricId);
532     metric_activation1->set_activation_type(ACTIVATE_IMMEDIATELY);
533     auto metric_activation2 = config.add_metric_activation();
534     metric_activation2->set_metric_id(metricId);
535     metric_activation2->set_activation_type(ACTIVATE_IMMEDIATELY);
536 
537     EXPECT_EQ(initConfig(config),
538               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS, metricId));
539 }
540 
TEST_F(MetricsManagerUtilTest,TestCountMetricMissingIdOrWhat)541 TEST_F(MetricsManagerUtilTest, TestCountMetricMissingIdOrWhat) {
542     StatsdConfig config;
543     int64_t metricId = 1;
544     CountMetric* metric = config.add_count_metric();
545     metric->set_id(metricId);
546 
547     EXPECT_EQ(initConfig(config),
548               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
549 }
550 
TEST_F(MetricsManagerUtilTest,TestCountMetricConditionlinkNoCondition)551 TEST_F(MetricsManagerUtilTest, TestCountMetricConditionlinkNoCondition) {
552     StatsdConfig config;
553     CountMetric* metric = config.add_count_metric();
554     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
555                                 /*condition=*/nullopt, /*states=*/{});
556     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
557 
558     auto link = metric->add_links();
559     link->set_condition(1);
560 
561     EXPECT_EQ(initConfig(config),
562               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
563                                   StringToId("Count")));
564 }
565 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingIdOrWhat)566 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingIdOrWhat) {
567     StatsdConfig config;
568     int64_t metricId = 1;
569     DurationMetric* metric = config.add_duration_metric();
570     metric->set_id(metricId);
571 
572     EXPECT_EQ(initConfig(config),
573               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
574 }
575 
TEST_F(MetricsManagerUtilTest,TestDurationMetricConditionlinkNoCondition)576 TEST_F(MetricsManagerUtilTest, TestDurationMetricConditionlinkNoCondition) {
577     StatsdConfig config;
578     DurationMetric* metric = config.add_duration_metric();
579     *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
580                                    /*condition=*/nullopt, /*states=*/{});
581     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
582     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
583     *config.add_predicate() = CreateScreenIsOnPredicate();
584 
585     auto link = metric->add_links();
586     link->set_condition(1);
587 
588     EXPECT_EQ(initConfig(config),
589               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
590                                   StringToId("Duration")));
591 }
592 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricMissingIdOrWhat)593 TEST_F(MetricsManagerUtilTest, TestGaugeMetricMissingIdOrWhat) {
594     StatsdConfig config;
595     int64_t metricId = 1;
596     GaugeMetric* metric = config.add_gauge_metric();
597     metric->set_id(metricId);
598 
599     EXPECT_EQ(initConfig(config),
600               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
601 }
602 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricConditionlinkNoCondition)603 TEST_F(MetricsManagerUtilTest, TestGaugeMetricConditionlinkNoCondition) {
604     StatsdConfig config;
605     GaugeMetric* metric = config.add_gauge_metric();
606     *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
607                                 /*samplingType=*/GaugeMetric_SamplingType_FIRST_N_SAMPLES,
608                                 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
609     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
610 
611     auto link = metric->add_links();
612     link->set_condition(1);
613 
614     EXPECT_EQ(initConfig(config),
615               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
616                                   StringToId("Gauge")));
617 }
618 
TEST_F(MetricsManagerUtilTest,TestEventMetricMissingIdOrWhat)619 TEST_F(MetricsManagerUtilTest, TestEventMetricMissingIdOrWhat) {
620     StatsdConfig config;
621     int64_t metricId = 1;
622     EventMetric* metric = config.add_event_metric();
623     metric->set_id(metricId);
624 
625     EXPECT_EQ(initConfig(config),
626               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
627 }
628 
TEST_F(MetricsManagerUtilTest,TestEventMetricConditionlinkNoCondition)629 TEST_F(MetricsManagerUtilTest, TestEventMetricConditionlinkNoCondition) {
630     StatsdConfig config;
631     EventMetric* metric = config.add_event_metric();
632     *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
633                                 /*condition=*/nullopt);
634     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
635 
636     auto link = metric->add_links();
637     link->set_condition(1);
638 
639     EXPECT_EQ(initConfig(config),
640               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
641                                   StringToId("Event")));
642 }
643 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMissingIdOrWhat)644 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMissingIdOrWhat) {
645     StatsdConfig config;
646     int64_t metricId = 1;
647     ValueMetric* metric = config.add_value_metric();
648     metric->set_id(metricId);
649 
650     EXPECT_EQ(initConfig(config),
651               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
652 }
653 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricConditionlinkNoCondition)654 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricConditionlinkNoCondition) {
655     StatsdConfig config;
656     ValueMetric* metric = config.add_value_metric();
657     *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
658                                 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
659     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
660 
661     auto link = metric->add_links();
662     link->set_condition(1);
663 
664     EXPECT_EQ(initConfig(config),
665               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
666                                   StringToId("NumericValue")));
667 }
668 
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingIdOrWhat)669 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingIdOrWhat) {
670     StatsdConfig config;
671     int64_t metricId = 1;
672     KllMetric* metric = config.add_kll_metric();
673     metric->set_id(metricId);
674 
675     EXPECT_EQ(initConfig(config),
676               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
677 }
678 
TEST_F(MetricsManagerUtilTest,TestKllMetricConditionlinkNoCondition)679 TEST_F(MetricsManagerUtilTest, TestKllMetricConditionlinkNoCondition) {
680     StatsdConfig config;
681     KllMetric* metric = config.add_kll_metric();
682     *metric = createKllMetric(/*name=*/"Kll", /*what=*/CreateScreenTurnedOnAtomMatcher(),
683                               /*valueField=*/2, /*condition=*/nullopt);
684     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
685 
686     auto link = metric->add_links();
687     link->set_condition(1);
688 
689     EXPECT_EQ(initConfig(config),
690               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
691                                   StringToId("Kll")));
692 }
693 
TEST_F(MetricsManagerUtilTest,TestMetricMatcherNotFound)694 TEST_F(MetricsManagerUtilTest, TestMetricMatcherNotFound) {
695     StatsdConfig config;
696     *config.add_count_metric() =
697             createCountMetric(/*name=*/"Count", /*what=*/StringToId("SOME MATCHER"),
698                               /*condition=*/nullopt, /*states=*/{});
699 
700     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
701                                           INVALID_CONFIG_REASON_METRIC_MATCHER_NOT_FOUND,
702                                           StringToId("Count"), StringToId("SOME MATCHER")));
703 }
704 
TEST_F(MetricsManagerUtilTest,TestMetricConditionLinkNotFound)705 TEST_F(MetricsManagerUtilTest, TestMetricConditionLinkNotFound) {
706     StatsdConfig config;
707     CountMetric* metric = config.add_count_metric();
708     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
709                                 /*condition=*/StringToId("ScreenIsOn"), /*states=*/{});
710     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
711     *config.add_predicate() = CreateScreenIsOnPredicate();
712 
713     auto link = metric->add_links();
714     link->set_condition(StringToId("SOME CONDITION"));
715 
716     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
717                                           INVALID_CONFIG_REASON_METRIC_CONDITION_LINK_NOT_FOUND,
718                                           StringToId("Count"), StringToId("SOME CONDITION")));
719 }
720 
TEST_F(MetricsManagerUtilTest,TestMetricStateNotFound)721 TEST_F(MetricsManagerUtilTest, TestMetricStateNotFound) {
722     StatsdConfig config;
723     *config.add_count_metric() =
724             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
725                               /*condition=*/nullopt, /*states=*/{StringToId("SOME STATE")});
726     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
727 
728     EXPECT_EQ(initConfig(config),
729               createInvalidConfigReasonWithState(INVALID_CONFIG_REASON_METRIC_STATE_NOT_FOUND,
730                                                  StringToId("Count"), StringToId("SOME STATE")));
731 }
732 
TEST_F(MetricsManagerUtilTest,TestMetricStatelinkNoState)733 TEST_F(MetricsManagerUtilTest, TestMetricStatelinkNoState) {
734     StatsdConfig config;
735     CountMetric* metric = config.add_count_metric();
736     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
737                                 /*condition=*/nullopt, /*states=*/{});
738     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
739 
740     auto link = metric->add_state_link();
741     link->set_state_atom_id(2);
742 
743     EXPECT_EQ(initConfig(config),
744               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE,
745                                   StringToId("Count")));
746 }
747 
TEST_F(MetricsManagerUtilTest,TestMetricBadThreshold)748 TEST_F(MetricsManagerUtilTest, TestMetricBadThreshold) {
749     StatsdConfig config;
750     CountMetric* metric = config.add_count_metric();
751     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
752                                 /*condition=*/nullopt, /*states=*/{});
753     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
754 
755     metric->mutable_threshold()->set_lt_float(1.0);
756 
757     EXPECT_EQ(initConfig(config),
758               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_BAD_THRESHOLD, StringToId("Count")));
759 }
760 
TEST_F(MetricsManagerUtilTest,TestMetricActivationMatcherNotFound)761 TEST_F(MetricsManagerUtilTest, TestMetricActivationMatcherNotFound) {
762     StatsdConfig config;
763     *config.add_count_metric() =
764             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
765                               /*condition=*/nullopt, /*states=*/{});
766     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
767     auto metric_activation = config.add_metric_activation();
768     metric_activation->set_metric_id(StringToId("Count"));
769     metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
770     auto event_activation = metric_activation->add_event_activation();
771 
772     event_activation->set_atom_matcher_id(StringToId("SOME_MATCHER"));
773 
774     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
775                                           INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND,
776                                           StringToId("Count"), StringToId("SOME_MATCHER")));
777 }
778 
TEST_F(MetricsManagerUtilTest,TestMetricDeactivationMatcherNotFound)779 TEST_F(MetricsManagerUtilTest, TestMetricDeactivationMatcherNotFound) {
780     StatsdConfig config;
781     *config.add_count_metric() =
782             createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
783                               /*condition=*/nullopt, /*states=*/{});
784     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
785     auto metric_activation = config.add_metric_activation();
786     metric_activation->set_metric_id(StringToId("Count"));
787     metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
788     auto event_activation = metric_activation->add_event_activation();
789     event_activation->set_atom_matcher_id(StringToId("ScreenTurnedOn"));
790 
791     event_activation->set_deactivation_atom_matcher_id(StringToId("SOME_MATCHER"));
792 
793     EXPECT_EQ(initConfig(config),
794               createInvalidConfigReasonWithMatcher(
795                       INVALID_CONFIG_REASON_METRIC_DEACTIVATION_MATCHER_NOT_FOUND,
796                       StringToId("Count"), StringToId("SOME_MATCHER")));
797 }
798 
TEST_F(MetricsManagerUtilTest,TestMetricSlicedStateAtomAllowedFromAnyUid)799 TEST_F(MetricsManagerUtilTest, TestMetricSlicedStateAtomAllowedFromAnyUid) {
800     StatsdConfig config;
801     CountMetric* metric = config.add_count_metric();
802     *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
803                                 /*condition=*/nullopt, /*states=*/{});
804     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
805 
806     *config.add_state() = CreateScreenState();
807     metric->add_slice_by_state(StringToId("ScreenState"));
808     config.add_whitelisted_atom_ids(util::SCREEN_STATE_CHANGED);
809 
810     EXPECT_EQ(
811             initConfig(config),
812             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
813                                 StringToId("Count")));
814 }
815 
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotSimple)816 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotSimple) {
817     StatsdConfig config;
818     *config.add_duration_metric() =
819             createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsEitherOnOff"),
820                                  /*condition=*/nullopt, /*states=*/{});
821     *config.add_predicate() = CreateScreenIsOnPredicate();
822     *config.add_predicate() = CreateScreenIsOffPredicate();
823 
824     auto condition = config.add_predicate();
825     condition->set_id(StringToId("ScreenIsEitherOnOff"));
826     Predicate_Combination* combination = condition->mutable_combination();
827     combination->set_operation(LogicalOperation::OR);
828     combination->add_predicate(StringToId("ScreenIsOn"));
829     combination->add_predicate(StringToId("ScreenIsOff"));
830 
831     EXPECT_EQ(initConfig(config),
832               createInvalidConfigReasonWithPredicate(
833                       INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_SIMPLE, StringToId("Duration"),
834                       StringToId("ScreenIsEitherOnOff")));
835 }
836 
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotFound)837 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotFound) {
838     StatsdConfig config;
839     int64_t metricId = 1;
840     DurationMetric* metric = config.add_duration_metric();
841     metric->set_id(metricId);
842 
843     metric->set_what(StringToId("SOME WHAT"));
844 
845     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
846                                           INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_FOUND,
847                                           metricId, StringToId("SOME WHAT")));
848 }
849 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingStart)850 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingStart) {
851     StatsdConfig config;
852     *config.add_duration_metric() =
853             createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("SCREEN_IS_ON"),
854                                  /*condition=*/nullopt, /*states=*/{});
855     auto condition = config.add_predicate();
856     condition->set_id(StringToId("SCREEN_IS_ON"));
857 
858     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
859     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
860 
861     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
862                                           INVALID_CONFIG_REASON_DURATION_METRIC_MISSING_START,
863                                           StringToId("Duration"), StringToId("SCREEN_IS_ON")));
864 }
865 
TEST_F(MetricsManagerUtilTest,TestDurationMetricMaxSparseHasSpliceByState)866 TEST_F(MetricsManagerUtilTest, TestDurationMetricMaxSparseHasSpliceByState) {
867     StatsdConfig config;
868     DurationMetric* metric = config.add_duration_metric();
869     *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
870                                    /*condition=*/nullopt, /*states=*/{});
871     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
872     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
873     *config.add_predicate() = CreateScreenIsOnPredicate();
874     *config.add_state() = CreateScreenState();
875 
876     metric->add_slice_by_state(StringToId("ScreenState"));
877     metric->set_aggregation_type(DurationMetric::MAX_SPARSE);
878 
879     EXPECT_EQ(
880             initConfig(config),
881             InvalidConfigReason(INVALID_CONFIG_REASON_DURATION_METRIC_MAX_SPARSE_HAS_SLICE_BY_STATE,
882                                 StringToId("Duration")));
883 }
884 
TEST_F(MetricsManagerUtilTest,TestValueMetricMissingValueField)885 TEST_F(MetricsManagerUtilTest, TestValueMetricMissingValueField) {
886     StatsdConfig config;
887     int64_t metricId = 1;
888     ValueMetric* metric = config.add_value_metric();
889     metric->set_id(metricId);
890     metric->set_what(1);
891 
892     EXPECT_EQ(
893             initConfig(config),
894             InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_MISSING_VALUE_FIELD, metricId));
895 }
896 
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasPositionAll)897 TEST_F(MetricsManagerUtilTest, TestValueMetricValueFieldHasPositionAll) {
898     StatsdConfig config;
899     int64_t metricId = 1;
900     ValueMetric* metric = config.add_value_metric();
901     metric->set_id(metricId);
902     metric->set_what(1);
903 
904     metric->mutable_value_field()->set_position(ALL);
905 
906     EXPECT_EQ(initConfig(config),
907               InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL,
908                                   metricId));
909 }
910 
TEST_F(MetricsManagerUtilTest,TestValueMetricHasIncorrectValueField)911 TEST_F(MetricsManagerUtilTest, TestValueMetricHasIncorrectValueField) {
912     StatsdConfig config;
913     int64_t metricId = 1;
914     ValueMetric* metric = config.add_value_metric();
915     metric->set_id(metricId);
916     metric->set_what(1);
917 
918     metric->mutable_value_field()->set_position(ANY);
919 
920     EXPECT_EQ(initConfig(config),
921               InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HAS_INCORRECT_VALUE_FIELD,
922                                   metricId));
923 }
924 
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingKllField)925 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingKllField) {
926     StatsdConfig config;
927     int64_t metricId = 1;
928     KllMetric* metric = config.add_kll_metric();
929     metric->set_id(metricId);
930     metric->set_what(1);
931 
932     EXPECT_EQ(initConfig(config),
933               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_MISSING_KLL_FIELD, metricId));
934 }
935 
TEST_F(MetricsManagerUtilTest,TestKllMetricKllFieldHasPositionAll)936 TEST_F(MetricsManagerUtilTest, TestKllMetricKllFieldHasPositionAll) {
937     StatsdConfig config;
938     int64_t metricId = 1;
939     KllMetric* metric = config.add_kll_metric();
940     metric->set_id(metricId);
941     metric->set_what(1);
942 
943     metric->mutable_kll_field()->set_position(ALL);
944 
945     EXPECT_EQ(initConfig(config),
946               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_KLL_FIELD_HAS_POSITION_ALL,
947                                   metricId));
948 }
949 
TEST_F(MetricsManagerUtilTest,TestKllMetricHasIncorrectKllField)950 TEST_F(MetricsManagerUtilTest, TestKllMetricHasIncorrectKllField) {
951     StatsdConfig config;
952     int64_t metricId = 1;
953     KllMetric* metric = config.add_kll_metric();
954     metric->set_id(metricId);
955     metric->set_what(1);
956 
957     metric->mutable_kll_field()->set_position(ANY);
958 
959     EXPECT_EQ(initConfig(config),
960               InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_HAS_INCORRECT_KLL_FIELD,
961                                   metricId));
962 }
963 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricIncorrectFieldFilter)964 TEST_F(MetricsManagerUtilTest, TestGaugeMetricIncorrectFieldFilter) {
965     StatsdConfig config;
966     int64_t metricId = 1;
967     GaugeMetric* metric = config.add_gauge_metric();
968     metric->set_id(metricId);
969     metric->set_what(1);
970 
971     EXPECT_EQ(initConfig(config),
972               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_INCORRECT_FIELD_FILTER,
973                                   metricId));
974 }
975 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoPullAtom)976 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoPullAtom) {
977     StatsdConfig config;
978     int64_t metricId = 1;
979     GaugeMetric* metric = config.add_gauge_metric();
980     metric->set_id(metricId);
981     metric->set_what(StringToId("ScreenTurnedOn"));
982     metric->mutable_gauge_fields_filter()->set_include_all(true);
983     metric->set_trigger_event(1);
984 
985     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
986 
987     EXPECT_EQ(
988             initConfig(config),
989             InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_PULL_ATOM, metricId));
990 }
991 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoFirstNSamples)992 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoFirstNSamples) {
993     StatsdConfig config;
994     int64_t metricId = 1;
995     GaugeMetric* metric = config.add_gauge_metric();
996     metric->set_id(metricId);
997     metric->set_what(StringToId("Matcher"));
998     *config.add_atom_matcher() =
999             CreateSimpleAtomMatcher(/*name=*/"Matcher", /*atomId=*/util::SUBSYSTEM_SLEEP_STATE);
1000 
1001     metric->mutable_gauge_fields_filter()->set_include_all(true);
1002     metric->set_trigger_event(StringToId("Matcher"));
1003 
1004     EXPECT_EQ(initConfig(config),
1005               InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_FIRST_N_SAMPLES,
1006                                   metricId));
1007 }
1008 
TEST_F(MetricsManagerUtilTest,TestMatcherDuplicate)1009 TEST_F(MetricsManagerUtilTest, TestMatcherDuplicate) {
1010     StatsdConfig config;
1011 
1012     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1013     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1014 
1015     EXPECT_EQ(initConfig(config),
1016               createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
1017                                                    StringToId("ScreenTurnedOn")));
1018 }
1019 
TEST_F(MetricsManagerUtilTest,TestMatcherNoOperation)1020 TEST_F(MetricsManagerUtilTest, TestMatcherNoOperation) {
1021     StatsdConfig config;
1022     int64_t matcherId = 1;
1023 
1024     AtomMatcher* matcher = config.add_atom_matcher();
1025     matcher->set_id(matcherId);
1026     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1027 
1028     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
1029                                           INVALID_CONFIG_REASON_MATCHER_NO_OPERATION, matcherId));
1030 }
1031 
TEST_F(MetricsManagerUtilTest,TestMatcherNotOperationIsNotUnary)1032 TEST_F(MetricsManagerUtilTest, TestMatcherNotOperationIsNotUnary) {
1033     StatsdConfig config;
1034     int64_t matcherId = 1;
1035     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1036     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
1037 
1038     AtomMatcher* matcher = config.add_atom_matcher();
1039     matcher->set_id(matcherId);
1040     matcher->mutable_combination()->set_operation(LogicalOperation::NOT);
1041     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1042     matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOff"));
1043 
1044     EXPECT_EQ(initConfig(config),
1045               createInvalidConfigReasonWithMatcher(
1046                       INVALID_CONFIG_REASON_MATCHER_NOT_OPERATION_IS_NOT_UNARY, matcherId));
1047 }
1048 
TEST_F(MetricsManagerUtilTest,TestConditionChildNotFound)1049 TEST_F(MetricsManagerUtilTest, TestConditionChildNotFound) {
1050     StatsdConfig config;
1051     int64_t conditionId = 1;
1052     int64_t childConditionId = 2;
1053 
1054     Predicate* condition = config.add_predicate();
1055     condition->set_id(conditionId);
1056     condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1057     condition->mutable_combination()->add_predicate(childConditionId);
1058 
1059     optional<InvalidConfigReason> expectedInvalidConfigReason =
1060             createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CHILD_NOT_FOUND,
1061                                                    conditionId);
1062     expectedInvalidConfigReason->conditionIds.push_back(childConditionId);
1063     EXPECT_EQ(initConfig(config), expectedInvalidConfigReason);
1064 }
1065 
TEST_F(MetricsManagerUtilTest,TestConditionDuplicate)1066 TEST_F(MetricsManagerUtilTest, TestConditionDuplicate) {
1067     StatsdConfig config;
1068     *config.add_predicate() = CreateScreenIsOnPredicate();
1069     *config.add_predicate() = CreateScreenIsOnPredicate();
1070 
1071     EXPECT_EQ(initConfig(config),
1072               createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
1073                                                      StringToId("ScreenIsOn")));
1074 }
1075 
TEST_F(MetricsManagerUtilTest,TestConditionNoOperation)1076 TEST_F(MetricsManagerUtilTest, TestConditionNoOperation) {
1077     StatsdConfig config;
1078     int64_t conditionId = 1;
1079     *config.add_predicate() = CreateScreenIsOnPredicate();
1080 
1081     Predicate* condition = config.add_predicate();
1082     condition->set_id(conditionId);
1083     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1084 
1085     EXPECT_EQ(initConfig(config),
1086               createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_NO_OPERATION,
1087                                                      conditionId));
1088 }
1089 
TEST_F(MetricsManagerUtilTest,TestConditionNotOperationIsNotUnary)1090 TEST_F(MetricsManagerUtilTest, TestConditionNotOperationIsNotUnary) {
1091     StatsdConfig config;
1092     int64_t conditionId = 1;
1093     *config.add_predicate() = CreateScreenIsOnPredicate();
1094     *config.add_predicate() = CreateScreenIsOffPredicate();
1095 
1096     Predicate* condition = config.add_predicate();
1097     condition->set_id(conditionId);
1098     condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1099     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1100     condition->mutable_combination()->add_predicate(StringToId("ScreenIsOff"));
1101 
1102     EXPECT_EQ(initConfig(config),
1103               createInvalidConfigReasonWithPredicate(
1104                       INVALID_CONFIG_REASON_CONDITION_NOT_OPERATION_IS_NOT_UNARY, conditionId));
1105 }
1106 
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlert)1107 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlert) {
1108     StatsdConfig config;
1109     int64_t alertId = 1;
1110     *config.add_subscription() = createSubscription("Subscription", Subscription::ALERT, alertId);
1111 
1112     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlert(
1113                                           INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1114                                           StringToId("Subscription"), alertId));
1115 }
1116 
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlarm)1117 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlarm) {
1118     StatsdConfig config;
1119     int64_t alarmId = 1;
1120     *config.add_subscription() = createSubscription("Subscription", Subscription::ALARM, alarmId);
1121 
1122     EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlarm(
1123                                           INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1124                                           StringToId("Subscription"), alarmId));
1125 }
1126 
TEST_F(MetricsManagerUtilTest,TestSubscriptionSubscriberInfoMissing)1127 TEST_F(MetricsManagerUtilTest, TestSubscriptionSubscriberInfoMissing) {
1128     StatsdConfig config;
1129     Subscription subscription =
1130             createSubscription("Subscription", Subscription::ALERT, /*alert id=*/1);
1131     subscription.clear_subscriber_information();
1132     *config.add_subscription() = subscription;
1133 
1134     EXPECT_EQ(initConfig(config),
1135               createInvalidConfigReasonWithSubscription(
1136                       INVALID_CONFIG_REASON_SUBSCRIPTION_SUBSCRIBER_INFO_MISSING,
1137                       StringToId("Subscription")));
1138 }
1139 
TEST_F(MetricsManagerUtilTest,TestAlarmPeriodLessThanOrEqualZero)1140 TEST_F(MetricsManagerUtilTest, TestAlarmPeriodLessThanOrEqualZero) {
1141     StatsdConfig config;
1142     *config.add_alarm() = createAlarm("Alarm", /*offset=*/1, /*period=*/-1);
1143 
1144     EXPECT_EQ(initConfig(config),
1145               createInvalidConfigReasonWithAlarm(
1146                       INVALID_CONFIG_REASON_ALARM_PERIOD_LESS_THAN_OR_EQUAL_ZERO,
1147                       StringToId("Alarm")));
1148 }
1149 
TEST_F(MetricsManagerUtilTest,TestAlarmOffsetLessThanOrEqualZero)1150 TEST_F(MetricsManagerUtilTest, TestAlarmOffsetLessThanOrEqualZero) {
1151     StatsdConfig config;
1152     *config.add_alarm() = createAlarm("Alarm", /*offset=*/-1, /*period=*/1);
1153 
1154     EXPECT_EQ(initConfig(config),
1155               createInvalidConfigReasonWithAlarm(
1156                       INVALID_CONFIG_REASON_ALARM_OFFSET_LESS_THAN_OR_EQUAL_ZERO,
1157                       StringToId("Alarm")));
1158 }
1159 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerInvalidMatcher)1160 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerInvalidMatcher) {
1161     sp<UidMap> uidMap = new UidMap();
1162     AtomMatcher matcher;
1163     // Matcher has no contents_case (simple/combination), so it is invalid.
1164     matcher.set_id(21);
1165     optional<InvalidConfigReason> invalidConfigReason;
1166     EXPECT_EQ(createAtomMatchingTracker(matcher, 0, uidMap, invalidConfigReason), nullptr);
1167     EXPECT_EQ(invalidConfigReason,
1168               createInvalidConfigReasonWithMatcher(
1169                       INVALID_CONFIG_REASON_MATCHER_MALFORMED_CONTENTS_CASE, matcher.id()));
1170 }
1171 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerSimple)1172 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerSimple) {
1173     int index = 1;
1174     int64_t id = 123;
1175     sp<UidMap> uidMap = new UidMap();
1176     AtomMatcher matcher;
1177     matcher.set_id(id);
1178     SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
1179     simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
1180     simpleAtomMatcher->add_field_value_matcher()->set_field(
1181             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
1182     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
1183             android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1184 
1185     optional<InvalidConfigReason> invalidConfigReason;
1186     sp<AtomMatchingTracker> tracker =
1187             createAtomMatchingTracker(matcher, index, uidMap, invalidConfigReason);
1188     EXPECT_NE(tracker, nullptr);
1189     EXPECT_EQ(invalidConfigReason, nullopt);
1190 
1191     EXPECT_TRUE(tracker->mInitialized);
1192     EXPECT_EQ(tracker->getId(), id);
1193     EXPECT_EQ(tracker->mIndex, index);
1194     const set<int>& atomIds = tracker->getAtomIds();
1195     ASSERT_EQ(atomIds.size(), 1);
1196     EXPECT_EQ(atomIds.count(SCREEN_STATE_ATOM_ID), 1);
1197 }
1198 
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerCombination)1199 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerCombination) {
1200     int index = 1;
1201     int64_t id = 123;
1202     sp<UidMap> uidMap = new UidMap();
1203     AtomMatcher matcher;
1204     matcher.set_id(id);
1205     AtomMatcher_Combination* combination = matcher.mutable_combination();
1206     combination->set_operation(LogicalOperation::OR);
1207     combination->add_matcher(123);
1208     combination->add_matcher(223);
1209 
1210     optional<InvalidConfigReason> invalidConfigReason;
1211     sp<AtomMatchingTracker> tracker =
1212             createAtomMatchingTracker(matcher, index, uidMap, invalidConfigReason);
1213     EXPECT_NE(tracker, nullptr);
1214     EXPECT_EQ(invalidConfigReason, nullopt);
1215 
1216     // Combination matchers need to be initialized first.
1217     EXPECT_FALSE(tracker->mInitialized);
1218     EXPECT_EQ(tracker->getId(), id);
1219     EXPECT_EQ(tracker->mIndex, index);
1220     const set<int>& atomIds = tracker->getAtomIds();
1221     ASSERT_EQ(atomIds.size(), 0);
1222 }
1223 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerInvalid)1224 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerInvalid) {
1225     const ConfigKey key(123, 456);
1226     // Predicate has no contents_case (simple/combination), so it is invalid.
1227     Predicate predicate;
1228     predicate.set_id(21);
1229     unordered_map<int64_t, int> atomTrackerMap;
1230     optional<InvalidConfigReason> invalidConfigReason;
1231     EXPECT_EQ(createConditionTracker(key, predicate, 0, atomTrackerMap, invalidConfigReason),
1232               nullptr);
1233     EXPECT_EQ(invalidConfigReason,
1234               createInvalidConfigReasonWithPredicate(
1235                       INVALID_CONFIG_REASON_CONDITION_MALFORMED_CONTENTS_CASE, predicate.id()));
1236 }
1237 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerSimple)1238 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerSimple) {
1239     int index = 1;
1240     int64_t id = 987;
1241     const ConfigKey key(123, 456);
1242 
1243     int startMatcherIndex = 2, stopMatcherIndex = 0, stopAllMatcherIndex = 1;
1244     int64_t startMatcherId = 246, stopMatcherId = 153, stopAllMatcherId = 975;
1245 
1246     Predicate predicate;
1247     predicate.set_id(id);
1248     SimplePredicate* simplePredicate = predicate.mutable_simple_predicate();
1249     simplePredicate->set_start(startMatcherId);
1250     simplePredicate->set_stop(stopMatcherId);
1251     simplePredicate->set_stop_all(stopAllMatcherId);
1252 
1253     unordered_map<int64_t, int> atomTrackerMap;
1254     atomTrackerMap[startMatcherId] = startMatcherIndex;
1255     atomTrackerMap[stopMatcherId] = stopMatcherIndex;
1256     atomTrackerMap[stopAllMatcherId] = stopAllMatcherIndex;
1257 
1258     optional<InvalidConfigReason> invalidConfigReason;
1259     sp<ConditionTracker> tracker =
1260             createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1261     EXPECT_EQ(invalidConfigReason, nullopt);
1262     EXPECT_EQ(tracker->getConditionId(), id);
1263     EXPECT_EQ(tracker->isSliced(), false);
1264     EXPECT_TRUE(tracker->IsSimpleCondition());
1265     const set<int>& interestedMatchers = tracker->getAtomMatchingTrackerIndex();
1266     ASSERT_EQ(interestedMatchers.size(), 3);
1267     ASSERT_EQ(interestedMatchers.count(startMatcherIndex), 1);
1268     ASSERT_EQ(interestedMatchers.count(stopMatcherIndex), 1);
1269     ASSERT_EQ(interestedMatchers.count(stopAllMatcherIndex), 1);
1270 }
1271 
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerCombination)1272 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerCombination) {
1273     int index = 1;
1274     int64_t id = 987;
1275     const ConfigKey key(123, 456);
1276 
1277     Predicate predicate;
1278     predicate.set_id(id);
1279     Predicate_Combination* combinationPredicate = predicate.mutable_combination();
1280     combinationPredicate->set_operation(LogicalOperation::AND);
1281     combinationPredicate->add_predicate(888);
1282     combinationPredicate->add_predicate(777);
1283 
1284     // Combination conditions must be initialized to set most state.
1285     unordered_map<int64_t, int> atomTrackerMap;
1286     optional<InvalidConfigReason> invalidConfigReason;
1287     sp<ConditionTracker> tracker =
1288             createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1289     EXPECT_EQ(invalidConfigReason, nullopt);
1290     EXPECT_EQ(tracker->getConditionId(), id);
1291     EXPECT_FALSE(tracker->IsSimpleCondition());
1292 }
1293 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerInvalidMetric)1294 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerInvalidMetric) {
1295     Alert alert;
1296     alert.set_id(123);
1297     alert.set_metric_id(1);
1298     alert.set_trigger_if_sum_gt(1);
1299     alert.set_num_buckets(1);
1300 
1301     sp<AlarmMonitor> anomalyAlarmMonitor;
1302     vector<sp<MetricProducer>> metricProducers;
1303     optional<InvalidConfigReason> invalidConfigReason;
1304     // Pass in empty metric producers, causing an error.
1305     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123, {},
1306                                    metricProducers, invalidConfigReason),
1307               nullopt);
1308     EXPECT_EQ(invalidConfigReason,
1309               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
1310                                                  alert.metric_id(), alert.id()));
1311 }
1312 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerNoThreshold)1313 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerNoThreshold) {
1314     int64_t metricId = 1;
1315     Alert alert;
1316     alert.set_id(123);
1317     alert.set_metric_id(metricId);
1318     alert.set_num_buckets(1);
1319 
1320     CountMetric metric;
1321     metric.set_id(metricId);
1322     metric.set_bucket(ONE_MINUTE);
1323     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1324     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
1325             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
1326     sp<AlarmMonitor> anomalyAlarmMonitor;
1327     optional<InvalidConfigReason> invalidConfigReason;
1328     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1329                                    {{1, 0}}, metricProducers, invalidConfigReason),
1330               nullopt);
1331     EXPECT_EQ(invalidConfigReason,
1332               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_THRESHOLD_MISSING,
1333                                                  alert.id()));
1334 }
1335 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerMissingBuckets)1336 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerMissingBuckets) {
1337     int64_t metricId = 1;
1338     Alert alert;
1339     alert.set_id(123);
1340     alert.set_metric_id(metricId);
1341     alert.set_trigger_if_sum_gt(1);
1342 
1343     CountMetric metric;
1344     metric.set_id(metricId);
1345     metric.set_bucket(ONE_MINUTE);
1346     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1347     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
1348             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
1349     sp<AlarmMonitor> anomalyAlarmMonitor;
1350     optional<InvalidConfigReason> invalidConfigReason;
1351     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1352                                    {{1, 0}}, metricProducers, invalidConfigReason),
1353               nullopt);
1354     EXPECT_EQ(invalidConfigReason,
1355               createInvalidConfigReasonWithAlert(
1356                       INVALID_CONFIG_REASON_ALERT_INVALID_TRIGGER_OR_NUM_BUCKETS, alert.id()));
1357 }
1358 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerGood)1359 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerGood) {
1360     int64_t metricId = 1;
1361     Alert alert;
1362     alert.set_id(123);
1363     alert.set_metric_id(metricId);
1364     alert.set_trigger_if_sum_gt(1);
1365     alert.set_num_buckets(1);
1366 
1367     CountMetric metric;
1368     metric.set_id(metricId);
1369     metric.set_bucket(ONE_MINUTE);
1370     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1371     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
1372             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
1373     sp<AlarmMonitor> anomalyAlarmMonitor;
1374     optional<InvalidConfigReason> invalidConfigReason;
1375     EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1376                                    {{1, 0}}, metricProducers, invalidConfigReason),
1377               nullopt);
1378     EXPECT_EQ(invalidConfigReason, nullopt);
1379 }
1380 
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerDurationTooLong)1381 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerDurationTooLong) {
1382     int64_t metricId = 1;
1383     Alert alert;
1384     alert.set_id(123);
1385     alert.set_metric_id(metricId);
1386     // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
1387     alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
1388     alert.set_num_buckets(1);
1389 
1390     DurationMetric metric;
1391     metric.set_id(metricId);
1392     metric.set_bucket(ONE_MINUTE);
1393     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
1394     FieldMatcher dimensions;
1395     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1396     vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
1397             kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
1398             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
1399             wizard, 0x0123456789, dimensions, 0, 0)});
1400     sp<AlarmMonitor> anomalyAlarmMonitor;
1401     optional<InvalidConfigReason> invalidConfigReason;
1402     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1403                                    {{1, 0}}, metricProducers, invalidConfigReason),
1404               nullopt);
1405     EXPECT_EQ(invalidConfigReason,
1406               createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_CANNOT_ADD_ANOMALY,
1407                                                  alert.metric_id(), alert.id()));
1408 }
1409 
TEST_F(MetricsManagerUtilTest,TestCreateDurationProducerDimensionsInWhatInvalid)1410 TEST_F(MetricsManagerUtilTest, TestCreateDurationProducerDimensionsInWhatInvalid) {
1411     StatsdConfig config;
1412     config.add_allowed_log_source("AID_ROOT");
1413     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1414     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1415     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
1416     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
1417 
1418     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1419     // The predicate is dimensioning by first attribution node by uid.
1420     FieldMatcher dimensions =
1421             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1422     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
1423     *config.add_predicate() = holdingWakelockPredicate;
1424 
1425     DurationMetric* durationMetric = config.add_duration_metric();
1426     durationMetric->set_id(StringToId("WakelockDuration"));
1427     durationMetric->set_what(holdingWakelockPredicate.id());
1428     durationMetric->set_aggregation_type(DurationMetric::SUM);
1429     // The metric is dimensioning by first attribution node by uid AND tag.
1430     // Invalid since the predicate only dimensions by uid.
1431     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
1432             util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
1433     durationMetric->set_bucket(FIVE_MINUTES);
1434 
1435     ConfigKey key(123, 987);
1436     uint64_t timeNs = 456;
1437     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1438     sp<AlarmMonitor> anomalyAlarmMonitor;
1439     sp<AlarmMonitor> periodicAlarmMonitor;
1440     sp<UidMap> uidMap;
1441     sp<MetricsManager> metricsManager =
1442             new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1443                                anomalyAlarmMonitor, periodicAlarmMonitor);
1444     EXPECT_FALSE(metricsManager->isConfigValid());
1445 }
1446 
TEST_F(MetricsManagerUtilTest,TestSampledMetrics)1447 TEST_F(MetricsManagerUtilTest, TestSampledMetrics) {
1448     StatsdConfig config;
1449     config.add_allowed_log_source("AID_ROOT");
1450 
1451     AtomMatcher appCrashMatcher =
1452             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1453     *config.add_atom_matcher() = appCrashMatcher;
1454 
1455     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1456     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1457 
1458     AtomMatcher bleScanResultReceivedMatcher = CreateSimpleAtomMatcher(
1459             "BleScanResultReceivedAtomMatcher", util::BLE_SCAN_RESULT_RECEIVED);
1460     *config.add_atom_matcher() = bleScanResultReceivedMatcher;
1461 
1462     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1463     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
1464             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1465     *config.add_predicate() = holdingWakelockPredicate;
1466 
1467     CountMetric sampledCountMetric =
1468             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1469     *sampledCountMetric.mutable_dimensions_in_what() =
1470             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1471     *sampledCountMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1472             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1473     sampledCountMetric.mutable_dimensional_sampling_info()->set_shard_count(2);
1474     *config.add_count_metric() = sampledCountMetric;
1475 
1476     CountMetric unsampledCountMetric =
1477             createCountMetric("CountAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1478     *unsampledCountMetric.mutable_dimensions_in_what() =
1479             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1480     *config.add_count_metric() = unsampledCountMetric;
1481 
1482     DurationMetric sampledDurationMetric = createDurationMetric(
1483             "DurationSampledWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1484     *sampledDurationMetric.mutable_dimensions_in_what() =
1485             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1486     *sampledDurationMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1487             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1488     sampledDurationMetric.mutable_dimensional_sampling_info()->set_shard_count(4);
1489     *config.add_duration_metric() = sampledDurationMetric;
1490 
1491     DurationMetric unsampledDurationMetric = createDurationMetric(
1492             "DurationWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1493     unsampledDurationMetric.set_aggregation_type(DurationMetric::SUM);
1494     *unsampledDurationMetric.mutable_dimensions_in_what() =
1495             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1496     *config.add_duration_metric() = unsampledDurationMetric;
1497 
1498     ValueMetric sampledValueMetric =
1499             createValueMetric("ValueSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1500                               /*num_results=*/2, nullopt, {});
1501     *sampledValueMetric.mutable_dimensions_in_what() =
1502             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1503     *sampledValueMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1504             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1505     sampledValueMetric.mutable_dimensional_sampling_info()->set_shard_count(6);
1506     *config.add_value_metric() = sampledValueMetric;
1507 
1508     ValueMetric unsampledValueMetric =
1509             createValueMetric("ValueBleScanResultsPerUid", bleScanResultReceivedMatcher,
1510                               /*num_results=*/2, nullopt, {});
1511     *unsampledValueMetric.mutable_dimensions_in_what() =
1512             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1513     *config.add_value_metric() = unsampledValueMetric;
1514 
1515     KllMetric sampledKllMetric =
1516             createKllMetric("KllSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1517                             /*num_results=*/2, nullopt);
1518     *sampledKllMetric.mutable_dimensions_in_what() =
1519             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1520     *sampledKllMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1521             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1522     sampledKllMetric.mutable_dimensional_sampling_info()->set_shard_count(8);
1523     *config.add_kll_metric() = sampledKllMetric;
1524 
1525     KllMetric unsampledKllMetric = createKllMetric(
1526             "KllBleScanResultsPerUid", bleScanResultReceivedMatcher, /*num_results=*/2, nullopt);
1527     *unsampledKllMetric.mutable_dimensions_in_what() =
1528             CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1529     *config.add_kll_metric() = unsampledKllMetric;
1530 
1531     GaugeMetric sampledGaugeMetric =
1532             createGaugeMetric("GaugeSampledAppCrashesPerUid", appCrashMatcher.id(),
1533                               GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1534     *sampledGaugeMetric.mutable_dimensions_in_what() =
1535             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1536     *sampledGaugeMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1537             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1538     sampledGaugeMetric.mutable_dimensional_sampling_info()->set_shard_count(10);
1539     *config.add_gauge_metric() = sampledGaugeMetric;
1540 
1541     GaugeMetric unsampledGaugeMetric =
1542             createGaugeMetric("GaugeAppCrashesPerUid", appCrashMatcher.id(),
1543                               GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1544     *unsampledGaugeMetric.mutable_dimensions_in_what() =
1545             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1546     *config.add_gauge_metric() = unsampledGaugeMetric;
1547 
1548     ConfigKey key(123, 987);
1549     uint64_t timeNs = 456;
1550     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1551     sp<AlarmMonitor> anomalyAlarmMonitor;
1552     sp<AlarmMonitor> periodicAlarmMonitor;
1553     sp<UidMap> uidMap;
1554     sp<MetricsManager> metricsManager =
1555             new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1556                                anomalyAlarmMonitor, periodicAlarmMonitor);
1557     ASSERT_TRUE(metricsManager->isConfigValid());
1558     ASSERT_EQ(10, metricsManager->mAllMetricProducers.size());
1559 
1560     sp<MetricProducer> sampledCountMetricProducer = metricsManager->mAllMetricProducers[0];
1561     sp<MetricProducer> unsampledCountMetricProducer = metricsManager->mAllMetricProducers[1];
1562     sp<MetricProducer> sampledDurationMetricProducer = metricsManager->mAllMetricProducers[2];
1563     sp<MetricProducer> unsampledDurationMetricProducer = metricsManager->mAllMetricProducers[3];
1564     sp<MetricProducer> sampledValueMetricProducer = metricsManager->mAllMetricProducers[4];
1565     sp<MetricProducer> unsampledValueMetricProducer = metricsManager->mAllMetricProducers[5];
1566     sp<MetricProducer> sampledKllMetricProducer = metricsManager->mAllMetricProducers[6];
1567     sp<MetricProducer> unsampledKllMetricProducer = metricsManager->mAllMetricProducers[7];
1568     sp<MetricProducer> sampledGaugeMetricProducer = metricsManager->mAllMetricProducers[8];
1569     sp<MetricProducer> unsampledGaugeMetricProducer = metricsManager->mAllMetricProducers[9];
1570 
1571     // Check shard count is set correctly for sampled metrics or set to default.
1572     EXPECT_EQ(2, sampledCountMetricProducer->mShardCount);
1573     EXPECT_EQ(0, unsampledCountMetricProducer->mShardCount);
1574     EXPECT_EQ(4, sampledDurationMetricProducer->mShardCount);
1575     EXPECT_EQ(0, unsampledDurationMetricProducer->mShardCount);
1576     EXPECT_EQ(6, sampledValueMetricProducer->mShardCount);
1577     EXPECT_EQ(0, unsampledValueMetricProducer->mShardCount);
1578     EXPECT_EQ(8, sampledKllMetricProducer->mShardCount);
1579     EXPECT_EQ(0, unsampledKllMetricProducer->mShardCount);
1580     EXPECT_EQ(10, sampledGaugeMetricProducer->mShardCount);
1581     EXPECT_EQ(0, unsampledGaugeMetricProducer->mShardCount);
1582 
1583     // Check sampled what fields is set correctly or empty.
1584     EXPECT_EQ(1, sampledCountMetricProducer->mSampledWhatFields.size());
1585     EXPECT_EQ(true, unsampledCountMetricProducer->mSampledWhatFields.empty());
1586     EXPECT_EQ(1, sampledDurationMetricProducer->mSampledWhatFields.size());
1587     EXPECT_EQ(true, unsampledDurationMetricProducer->mSampledWhatFields.empty());
1588     EXPECT_EQ(1, sampledValueMetricProducer->mSampledWhatFields.size());
1589     EXPECT_EQ(true, unsampledValueMetricProducer->mSampledWhatFields.empty());
1590     EXPECT_EQ(1, sampledKllMetricProducer->mSampledWhatFields.size());
1591     EXPECT_EQ(true, unsampledKllMetricProducer->mSampledWhatFields.empty());
1592     EXPECT_EQ(1, sampledGaugeMetricProducer->mSampledWhatFields.size());
1593     EXPECT_EQ(true, unsampledGaugeMetricProducer->mSampledWhatFields.empty());
1594 }
1595 
TEST_F(MetricsManagerUtilTest,TestMetricHasShardCountButNoSampledField)1596 TEST_F(MetricsManagerUtilTest, TestMetricHasShardCountButNoSampledField) {
1597     AtomMatcher appCrashMatcher =
1598             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1599 
1600     StatsdConfig config;
1601     config.add_allowed_log_source("AID_ROOT");
1602     *config.add_atom_matcher() = appCrashMatcher;
1603 
1604     CountMetric metric =
1605             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1606     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1607     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1608     *config.add_count_metric() = metric;
1609 
1610     EXPECT_EQ(initConfig(config),
1611               InvalidConfigReason(
1612                       INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_MISSING_SAMPLED_FIELD,
1613                       metric.id()));
1614 }
1615 
TEST_F(MetricsManagerUtilTest,TestMetricHasSampledFieldIncorrectShardCount)1616 TEST_F(MetricsManagerUtilTest, TestMetricHasSampledFieldIncorrectShardCount) {
1617     AtomMatcher appCrashMatcher =
1618             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1619 
1620     StatsdConfig config;
1621     config.add_allowed_log_source("AID_ROOT");
1622     *config.add_atom_matcher() = appCrashMatcher;
1623 
1624     CountMetric metric =
1625             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1626     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1627     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1628             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1629     *config.add_count_metric() = metric;
1630 
1631     EXPECT_EQ(initConfig(config),
1632               InvalidConfigReason(
1633                       INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_INCORRECT_SHARD_COUNT,
1634                       metric.id()));
1635 }
1636 
TEST_F(MetricsManagerUtilTest,TestMetricHasMultipleSampledFields)1637 TEST_F(MetricsManagerUtilTest, TestMetricHasMultipleSampledFields) {
1638     AtomMatcher appCrashMatcher =
1639             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1640 
1641     StatsdConfig config;
1642     config.add_allowed_log_source("AID_ROOT");
1643     *config.add_atom_matcher() = appCrashMatcher;
1644 
1645     CountMetric metric =
1646             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1647     *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1648     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1649             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/, 2 /*event_type*/});
1650     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1651     *config.add_count_metric() = metric;
1652 
1653     EXPECT_EQ(initConfig(config),
1654               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1655                                   metric.id()));
1656 }
1657 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionALL)1658 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionALL) {
1659     AtomMatcher testAtomReportedMatcher =
1660             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1661 
1662     StatsdConfig config;
1663     config.add_allowed_log_source("AID_ROOT");
1664     *config.add_atom_matcher() = testAtomReportedMatcher;
1665 
1666     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1667                                            testAtomReportedMatcher.id(), nullopt, {});
1668     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1669             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
1670     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1671             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1672                                      {Position::ALL});
1673     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1674     *config.add_count_metric() = metric;
1675 
1676     EXPECT_EQ(initConfig(config),
1677               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1678                                   metric.id()));
1679 }
1680 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionFIRST)1681 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionFIRST) {
1682     AtomMatcher testAtomReportedMatcher =
1683             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1684 
1685     StatsdConfig config;
1686     config.add_allowed_log_source("AID_ROOT");
1687     *config.add_atom_matcher() = testAtomReportedMatcher;
1688 
1689     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1690                                            testAtomReportedMatcher.id(), nullopt, {});
1691     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1692             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::FIRST});
1693     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1694             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1695                                      {Position::FIRST});
1696     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1697     *config.add_count_metric() = metric;
1698 
1699     EXPECT_EQ(initConfig(config), nullopt);
1700 }
1701 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionLAST)1702 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionLAST) {
1703     AtomMatcher testAtomReportedMatcher =
1704             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1705 
1706     StatsdConfig config;
1707     config.add_allowed_log_source("AID_ROOT");
1708     *config.add_atom_matcher() = testAtomReportedMatcher;
1709 
1710     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1711                                            testAtomReportedMatcher.id(), nullopt, {});
1712     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1713             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::LAST});
1714     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1715             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1716                                      {Position::LAST});
1717     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1718     *config.add_count_metric() = metric;
1719 
1720     EXPECT_EQ(initConfig(config), nullopt);
1721 }
1722 
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionANY)1723 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionANY) {
1724     AtomMatcher testAtomReportedMatcher =
1725             CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1726 
1727     StatsdConfig config;
1728     config.add_allowed_log_source("AID_ROOT");
1729     *config.add_atom_matcher() = testAtomReportedMatcher;
1730 
1731     CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1732                                            testAtomReportedMatcher.id(), nullopt, {});
1733     *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1734             util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ANY});
1735     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1736             CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1737                                      {Position::ALL});
1738     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1739     *config.add_count_metric() = metric;
1740 
1741     EXPECT_EQ(initConfig(config),
1742               InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1743                                   metric.id()));
1744 }
1745 
TEST_F(MetricsManagerUtilTest,TestMetricSampledFieldNotSubsetDimension)1746 TEST_F(MetricsManagerUtilTest, TestMetricSampledFieldNotSubsetDimension) {
1747     AtomMatcher appCrashMatcher =
1748             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1749 
1750     StatsdConfig config;
1751     config.add_allowed_log_source("AID_ROOT");
1752     *config.add_atom_matcher() = appCrashMatcher;
1753 
1754     CountMetric metric =
1755             createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1756     *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1757             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1758     metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1759     *config.add_count_metric() = metric;
1760 
1761     EXPECT_EQ(
1762             initConfig(config),
1763             InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1764                                 metric.id()));
1765 }
1766 
TEST_F(MetricsManagerUtilTest,TestCountMetricHasRestrictedDelegate)1767 TEST_F(MetricsManagerUtilTest, TestCountMetricHasRestrictedDelegate) {
1768     StatsdConfig config;
1769     CountMetric* metric = config.add_count_metric();
1770     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
1771 
1772     EXPECT_EQ(initConfig(config),
1773               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
1774 }
1775 
TEST_F(MetricsManagerUtilTest,TestDurationMetricHasRestrictedDelegate)1776 TEST_F(MetricsManagerUtilTest, TestDurationMetricHasRestrictedDelegate) {
1777     StatsdConfig config;
1778     DurationMetric* metric = config.add_duration_metric();
1779     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
1780 
1781     EXPECT_EQ(initConfig(config),
1782               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
1783 }
1784 
TEST_F(MetricsManagerUtilTest,TestGaugeMetricHasRestrictedDelegate)1785 TEST_F(MetricsManagerUtilTest, TestGaugeMetricHasRestrictedDelegate) {
1786     StatsdConfig config;
1787     GaugeMetric* metric = config.add_gauge_metric();
1788     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
1789 
1790     EXPECT_EQ(initConfig(config),
1791               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
1792 }
1793 
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHasRestrictedDelegate)1794 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHasRestrictedDelegate) {
1795     StatsdConfig config;
1796     ValueMetric* metric = config.add_value_metric();
1797     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
1798 
1799     EXPECT_EQ(initConfig(config),
1800               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
1801 }
1802 
TEST_F(MetricsManagerUtilTest,TestKllMetricHasRestrictedDelegate)1803 TEST_F(MetricsManagerUtilTest, TestKllMetricHasRestrictedDelegate) {
1804     StatsdConfig config;
1805     KllMetric* metric = config.add_kll_metric();
1806     config.set_restricted_metrics_delegate_package_name("com.android.app.test");
1807 
1808     EXPECT_EQ(initConfig(config),
1809               InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
1810 }
1811 
1812 }  // namespace statsd
1813 }  // namespace os
1814 }  // namespace android
1815 
1816 #else
1817 GTEST_LOG_(INFO) << "This test does nothing.\n";
1818 #endif
1819