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/statsd_config.pb.h"
27 #include "src/condition/ConditionTracker.h"
28 #include "src/matchers/AtomMatchingTracker.h"
29 #include "src/metrics/CountMetricProducer.h"
30 #include "src/metrics/DurationMetricProducer.h"
31 #include "src/metrics/GaugeMetricProducer.h"
32 #include "src/metrics/MetricProducer.h"
33 #include "src/metrics/ValueMetricProducer.h"
34 #include "src/state/StateManager.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 kAlertId = 3;
55 
56 const long timeBaseSec = 1000;
57 
buildGoodConfig()58 StatsdConfig buildGoodConfig() {
59     StatsdConfig config;
60     config.set_id(12345);
61 
62     AtomMatcher* eventMatcher = config.add_atom_matcher();
63     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
64 
65     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
66     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
67     simpleAtomMatcher->add_field_value_matcher()->set_field(
68             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
69     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
70             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
71 
72     eventMatcher = config.add_atom_matcher();
73     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
74 
75     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
76     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
77     simpleAtomMatcher->add_field_value_matcher()->set_field(
78             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
79     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
80             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
81 
82     eventMatcher = config.add_atom_matcher();
83     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
84 
85     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
86     combination->set_operation(LogicalOperation::OR);
87     combination->add_matcher(StringToId("SCREEN_IS_ON"));
88     combination->add_matcher(StringToId("SCREEN_IS_OFF"));
89 
90     CountMetric* metric = config.add_count_metric();
91     metric->set_id(3);
92     metric->set_what(StringToId("SCREEN_IS_ON"));
93     metric->set_bucket(ONE_MINUTE);
94     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
95     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
96 
97     config.add_no_report_metric(3);
98 
99     auto alert = config.add_alert();
100     alert->set_id(kAlertId);
101     alert->set_metric_id(3);
102     alert->set_num_buckets(10);
103     alert->set_refractory_period_secs(100);
104     alert->set_trigger_if_sum_gt(100);
105     return config;
106 }
107 
buildCircleMatchers()108 StatsdConfig buildCircleMatchers() {
109     StatsdConfig config;
110     config.set_id(12345);
111 
112     AtomMatcher* eventMatcher = config.add_atom_matcher();
113     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
114 
115     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
116     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
117     simpleAtomMatcher->add_field_value_matcher()->set_field(
118             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
119     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
120             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
121 
122     eventMatcher = config.add_atom_matcher();
123     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
124 
125     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
126     combination->set_operation(LogicalOperation::OR);
127     combination->add_matcher(StringToId("SCREEN_IS_ON"));
128     // Circle dependency
129     combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
130 
131     return config;
132 }
133 
buildAlertWithUnknownMetric()134 StatsdConfig buildAlertWithUnknownMetric() {
135     StatsdConfig config;
136     config.set_id(12345);
137 
138     AtomMatcher* eventMatcher = config.add_atom_matcher();
139     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
140 
141     CountMetric* metric = config.add_count_metric();
142     metric->set_id(3);
143     metric->set_what(StringToId("SCREEN_IS_ON"));
144     metric->set_bucket(ONE_MINUTE);
145     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
146     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
147 
148     auto alert = config.add_alert();
149     alert->set_id(3);
150     alert->set_metric_id(2);
151     alert->set_num_buckets(10);
152     alert->set_refractory_period_secs(100);
153     alert->set_trigger_if_sum_gt(100);
154     return config;
155 }
156 
buildMissingMatchers()157 StatsdConfig buildMissingMatchers() {
158     StatsdConfig config;
159     config.set_id(12345);
160 
161     AtomMatcher* eventMatcher = config.add_atom_matcher();
162     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
163 
164     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
165     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
166     simpleAtomMatcher->add_field_value_matcher()->set_field(
167             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
168     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
169             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
170 
171     eventMatcher = config.add_atom_matcher();
172     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
173 
174     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
175     combination->set_operation(LogicalOperation::OR);
176     combination->add_matcher(StringToId("SCREEN_IS_ON"));
177     // undefined matcher
178     combination->add_matcher(StringToId("ABC"));
179 
180     return config;
181 }
182 
buildMissingPredicate()183 StatsdConfig buildMissingPredicate() {
184     StatsdConfig config;
185     config.set_id(12345);
186 
187     CountMetric* metric = config.add_count_metric();
188     metric->set_id(3);
189     metric->set_what(StringToId("SCREEN_EVENT"));
190     metric->set_bucket(ONE_MINUTE);
191     metric->set_condition(StringToId("SOME_CONDITION"));
192 
193     AtomMatcher* eventMatcher = config.add_atom_matcher();
194     eventMatcher->set_id(StringToId("SCREEN_EVENT"));
195 
196     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
197     simpleAtomMatcher->set_atom_id(2);
198 
199     return config;
200 }
201 
buildDimensionMetricsWithMultiTags()202 StatsdConfig buildDimensionMetricsWithMultiTags() {
203     StatsdConfig config;
204     config.set_id(12345);
205 
206     AtomMatcher* eventMatcher = config.add_atom_matcher();
207     eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
208     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
209     simpleAtomMatcher->set_atom_id(2);
210 
211     eventMatcher = config.add_atom_matcher();
212     eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
213     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
214     simpleAtomMatcher->set_atom_id(3);
215 
216     eventMatcher = config.add_atom_matcher();
217     eventMatcher->set_id(StringToId("BATTERY_LOW"));
218 
219     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
220     combination->set_operation(LogicalOperation::OR);
221     combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
222     combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
223 
224     // Count process state changes, slice by uid, while SCREEN_IS_OFF
225     CountMetric* metric = config.add_count_metric();
226     metric->set_id(3);
227     metric->set_what(StringToId("BATTERY_LOW"));
228     metric->set_bucket(ONE_MINUTE);
229     // This case is interesting. We want to dimension across two atoms.
230     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
231 
232     auto alert = config.add_alert();
233     alert->set_id(kAlertId);
234     alert->set_metric_id(3);
235     alert->set_num_buckets(10);
236     alert->set_refractory_period_secs(100);
237     alert->set_trigger_if_sum_gt(100);
238     return config;
239 }
240 
buildCirclePredicates()241 StatsdConfig buildCirclePredicates() {
242     StatsdConfig config;
243     config.set_id(12345);
244 
245     AtomMatcher* eventMatcher = config.add_atom_matcher();
246     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
247 
248     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
249     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
250     simpleAtomMatcher->add_field_value_matcher()->set_field(
251             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
252     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
253             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
254 
255     eventMatcher = config.add_atom_matcher();
256     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
257 
258     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
259     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
260     simpleAtomMatcher->add_field_value_matcher()->set_field(
261             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
262     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
263             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
264 
265     auto condition = config.add_predicate();
266     condition->set_id(StringToId("SCREEN_IS_ON"));
267     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
268     simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
269     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
270 
271     condition = config.add_predicate();
272     condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
273 
274     Predicate_Combination* combination = condition->mutable_combination();
275     combination->set_operation(LogicalOperation::OR);
276     combination->add_predicate(StringToId("SCREEN_IS_ON"));
277     combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
278 
279     return config;
280 }
281 
buildConfigWithDifferentPredicates()282 StatsdConfig buildConfigWithDifferentPredicates() {
283     StatsdConfig config;
284     config.set_id(12345);
285 
286     auto pulledAtomMatcher =
287             CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
288     *config.add_atom_matcher() = pulledAtomMatcher;
289     auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
290     *config.add_atom_matcher() = screenOnAtomMatcher;
291     auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
292     *config.add_atom_matcher() = screenOffAtomMatcher;
293     auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
294     *config.add_atom_matcher() = batteryNoneAtomMatcher;
295     auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
296     *config.add_atom_matcher() = batteryUsbAtomMatcher;
297 
298     // Simple condition with InitialValue set to default (unknown).
299     auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
300     *config.add_predicate() = screenOnUnknownPredicate;
301 
302     // Simple condition with InitialValue set to false.
303     auto screenOnFalsePredicate = config.add_predicate();
304     screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
305     SimplePredicate* simpleScreenOnFalsePredicate =
306             screenOnFalsePredicate->mutable_simple_predicate();
307     simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
308     simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
309     simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
310 
311     // Simple condition with InitialValue set to false.
312     auto onBatteryFalsePredicate = config.add_predicate();
313     onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
314     SimplePredicate* simpleOnBatteryFalsePredicate =
315             onBatteryFalsePredicate->mutable_simple_predicate();
316     simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
317     simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
318     simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
319 
320     // Combination condition with both simple condition InitialValues set to false.
321     auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
322     screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
323     screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
324             LogicalOperation::AND);
325     addPredicateToPredicateCombination(*screenOnFalsePredicate,
326                                        screenOnFalseOnBatteryFalsePredicate);
327     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
328                                        screenOnFalseOnBatteryFalsePredicate);
329 
330     // Combination condition with one simple condition InitialValue set to unknown and one set to
331     // false.
332     auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
333     screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
334     screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
335             LogicalOperation::AND);
336     addPredicateToPredicateCombination(screenOnUnknownPredicate,
337                                        screenOnUnknownOnBatteryFalsePredicate);
338     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
339                                        screenOnUnknownOnBatteryFalsePredicate);
340 
341     // Simple condition metric with initial value false.
342     ValueMetric* metric1 = config.add_value_metric();
343     metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
344     metric1->set_what(pulledAtomMatcher.id());
345     *metric1->mutable_value_field() =
346             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
347     metric1->set_bucket(FIVE_MINUTES);
348     metric1->set_condition(screenOnFalsePredicate->id());
349 
350     // Simple condition metric with initial value unknown.
351     ValueMetric* metric2 = config.add_value_metric();
352     metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
353     metric2->set_what(pulledAtomMatcher.id());
354     *metric2->mutable_value_field() =
355             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
356     metric2->set_bucket(FIVE_MINUTES);
357     metric2->set_condition(screenOnUnknownPredicate.id());
358 
359     // Combination condition metric with initial values false and false.
360     ValueMetric* metric3 = config.add_value_metric();
361     metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
362     metric3->set_what(pulledAtomMatcher.id());
363     *metric3->mutable_value_field() =
364             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
365     metric3->set_bucket(FIVE_MINUTES);
366     metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
367 
368     // Combination condition metric with initial values unknown and false.
369     ValueMetric* metric4 = config.add_value_metric();
370     metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
371     metric4->set_what(pulledAtomMatcher.id());
372     *metric4->mutable_value_field() =
373             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
374     metric4->set_bucket(FIVE_MINUTES);
375     metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
376 
377     return config;
378 }
379 }  // anonymous namespace
380 
TEST(MetricsManagerTest,TestInitialConditions)381 TEST(MetricsManagerTest, TestInitialConditions) {
382     sp<UidMap> uidMap = new UidMap();
383     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
384     sp<AlarmMonitor> anomalyAlarmMonitor;
385     sp<AlarmMonitor> periodicAlarmMonitor;
386     StatsdConfig config = buildConfigWithDifferentPredicates();
387     set<int> allTagIds;
388     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
389     unordered_map<int64_t, int> atomMatchingTrackerMap;
390     vector<sp<ConditionTracker>> allConditionTrackers;
391     unordered_map<int64_t, int> conditionTrackerMap;
392     vector<sp<MetricProducer>> allMetricProducers;
393     unordered_map<int64_t, int> metricProducerMap;
394     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
395     std::vector<sp<AlarmTracker>> allAlarmTrackers;
396     unordered_map<int, std::vector<int>> conditionToMetricMap;
397     unordered_map<int, std::vector<int>> trackerToMetricMap;
398     unordered_map<int, std::vector<int>> trackerToConditionMap;
399     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
400     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
401     unordered_map<int64_t, int> alertTrackerMap;
402     vector<int> metricsWithActivation;
403     map<int64_t, uint64_t> stateProtoHashes;
404     std::set<int64_t> noReportMetricIds;
405 
406     EXPECT_TRUE(initStatsdConfig(
407             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
408             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
409             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
410             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
411             trackerToConditionMap, activationAtomTrackerToMetricMap,
412             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
413             stateProtoHashes, noReportMetricIds));
414     ASSERT_EQ(4u, allMetricProducers.size());
415     ASSERT_EQ(5u, allConditionTrackers.size());
416 
417     ConditionKey queryKey;
418     vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
419 
420     allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
421     allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
422     EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
423     EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
424     EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
425     EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
426     EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
427 
428     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
429     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
430     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
431     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
432 }
433 
TEST(MetricsManagerTest,TestGoodConfig)434 TEST(MetricsManagerTest, TestGoodConfig) {
435     sp<UidMap> uidMap = new UidMap();
436     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
437     sp<AlarmMonitor> anomalyAlarmMonitor;
438     sp<AlarmMonitor> periodicAlarmMonitor;
439     StatsdConfig config = buildGoodConfig();
440     set<int> allTagIds;
441     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
442     unordered_map<int64_t, int> atomMatchingTrackerMap;
443     vector<sp<ConditionTracker>> allConditionTrackers;
444     unordered_map<int64_t, int> conditionTrackerMap;
445     vector<sp<MetricProducer>> allMetricProducers;
446     unordered_map<int64_t, int> metricProducerMap;
447     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
448     std::vector<sp<AlarmTracker>> allAlarmTrackers;
449     unordered_map<int, std::vector<int>> conditionToMetricMap;
450     unordered_map<int, std::vector<int>> trackerToMetricMap;
451     unordered_map<int, std::vector<int>> trackerToConditionMap;
452     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
453     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
454     unordered_map<int64_t, int> alertTrackerMap;
455     vector<int> metricsWithActivation;
456     map<int64_t, uint64_t> stateProtoHashes;
457     std::set<int64_t> noReportMetricIds;
458 
459     EXPECT_TRUE(initStatsdConfig(
460             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
461             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
462             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
463             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
464             trackerToConditionMap, activationAtomTrackerToMetricMap,
465             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
466             stateProtoHashes, noReportMetricIds));
467     ASSERT_EQ(1u, allMetricProducers.size());
468     EXPECT_THAT(metricProducerMap, UnorderedElementsAre(Pair(config.count_metric(0).id(), 0)));
469     ASSERT_EQ(1u, allAnomalyTrackers.size());
470     ASSERT_EQ(1u, noReportMetricIds.size());
471     ASSERT_EQ(1u, alertTrackerMap.size());
472     EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
473     EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
474 }
475 
TEST(MetricsManagerTest,TestDimensionMetricsWithMultiTags)476 TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
477     sp<UidMap> uidMap = new UidMap();
478     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
479     sp<AlarmMonitor> anomalyAlarmMonitor;
480     sp<AlarmMonitor> periodicAlarmMonitor;
481     StatsdConfig config = buildDimensionMetricsWithMultiTags();
482     set<int> allTagIds;
483     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
484     unordered_map<int64_t, int> atomMatchingTrackerMap;
485     vector<sp<ConditionTracker>> allConditionTrackers;
486     unordered_map<int64_t, int> conditionTrackerMap;
487     vector<sp<MetricProducer>> allMetricProducers;
488     unordered_map<int64_t, int> metricProducerMap;
489     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
490     std::vector<sp<AlarmTracker>> allAlarmTrackers;
491     unordered_map<int, std::vector<int>> conditionToMetricMap;
492     unordered_map<int, std::vector<int>> trackerToMetricMap;
493     unordered_map<int, std::vector<int>> trackerToConditionMap;
494     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
495     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
496     unordered_map<int64_t, int> alertTrackerMap;
497     vector<int> metricsWithActivation;
498     map<int64_t, uint64_t> stateProtoHashes;
499     std::set<int64_t> noReportMetricIds;
500 
501     EXPECT_FALSE(initStatsdConfig(
502             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
503             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
504             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
505             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
506             trackerToConditionMap, activationAtomTrackerToMetricMap,
507             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
508             stateProtoHashes, noReportMetricIds));
509 }
510 
TEST(MetricsManagerTest,TestCircleLogMatcherDependency)511 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
512     sp<UidMap> uidMap = new UidMap();
513     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
514     sp<AlarmMonitor> anomalyAlarmMonitor;
515     sp<AlarmMonitor> periodicAlarmMonitor;
516     StatsdConfig config = buildCircleMatchers();
517     set<int> allTagIds;
518     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
519     unordered_map<int64_t, int> atomMatchingTrackerMap;
520     vector<sp<ConditionTracker>> allConditionTrackers;
521     unordered_map<int64_t, int> conditionTrackerMap;
522     vector<sp<MetricProducer>> allMetricProducers;
523     unordered_map<int64_t, int> metricProducerMap;
524     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
525     std::vector<sp<AlarmTracker>> allAlarmTrackers;
526     unordered_map<int, std::vector<int>> conditionToMetricMap;
527     unordered_map<int, std::vector<int>> trackerToMetricMap;
528     unordered_map<int, std::vector<int>> trackerToConditionMap;
529     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
530     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
531     unordered_map<int64_t, int> alertTrackerMap;
532     vector<int> metricsWithActivation;
533     map<int64_t, uint64_t> stateProtoHashes;
534     std::set<int64_t> noReportMetricIds;
535 
536     EXPECT_FALSE(initStatsdConfig(
537             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
538             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
539             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
540             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
541             trackerToConditionMap, activationAtomTrackerToMetricMap,
542             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
543             stateProtoHashes, noReportMetricIds));
544 }
545 
TEST(MetricsManagerTest,TestMissingMatchers)546 TEST(MetricsManagerTest, TestMissingMatchers) {
547     sp<UidMap> uidMap = new UidMap();
548     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
549     sp<AlarmMonitor> anomalyAlarmMonitor;
550     sp<AlarmMonitor> periodicAlarmMonitor;
551     StatsdConfig config = buildMissingMatchers();
552     set<int> allTagIds;
553     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
554     unordered_map<int64_t, int> atomMatchingTrackerMap;
555     vector<sp<ConditionTracker>> allConditionTrackers;
556     unordered_map<int64_t, int> conditionTrackerMap;
557     vector<sp<MetricProducer>> allMetricProducers;
558     unordered_map<int64_t, int> metricProducerMap;
559     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
560     std::vector<sp<AlarmTracker>> allAlarmTrackers;
561     unordered_map<int, std::vector<int>> conditionToMetricMap;
562     unordered_map<int, std::vector<int>> trackerToMetricMap;
563     unordered_map<int, std::vector<int>> trackerToConditionMap;
564     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
565     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
566     unordered_map<int64_t, int> alertTrackerMap;
567     vector<int> metricsWithActivation;
568     map<int64_t, uint64_t> stateProtoHashes;
569     std::set<int64_t> noReportMetricIds;
570     EXPECT_FALSE(initStatsdConfig(
571             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
572             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
573             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
574             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
575             trackerToConditionMap, activationAtomTrackerToMetricMap,
576             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
577             stateProtoHashes, noReportMetricIds));
578 }
579 
TEST(MetricsManagerTest,TestMissingPredicate)580 TEST(MetricsManagerTest, TestMissingPredicate) {
581     sp<UidMap> uidMap = new UidMap();
582     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
583     sp<AlarmMonitor> anomalyAlarmMonitor;
584     sp<AlarmMonitor> periodicAlarmMonitor;
585     StatsdConfig config = buildMissingPredicate();
586     set<int> allTagIds;
587     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
588     unordered_map<int64_t, int> atomMatchingTrackerMap;
589     vector<sp<ConditionTracker>> allConditionTrackers;
590     unordered_map<int64_t, int> conditionTrackerMap;
591     vector<sp<MetricProducer>> allMetricProducers;
592     unordered_map<int64_t, int> metricProducerMap;
593     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
594     std::vector<sp<AlarmTracker>> allAlarmTrackers;
595     unordered_map<int, std::vector<int>> conditionToMetricMap;
596     unordered_map<int, std::vector<int>> trackerToMetricMap;
597     unordered_map<int, std::vector<int>> trackerToConditionMap;
598     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
599     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
600     unordered_map<int64_t, int> alertTrackerMap;
601     vector<int> metricsWithActivation;
602     map<int64_t, uint64_t> stateProtoHashes;
603     std::set<int64_t> noReportMetricIds;
604     EXPECT_FALSE(initStatsdConfig(
605             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
606             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
607             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
608             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
609             trackerToConditionMap, activationAtomTrackerToMetricMap,
610             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
611             stateProtoHashes, noReportMetricIds));
612 }
613 
TEST(MetricsManagerTest,TestCirclePredicateDependency)614 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
615     sp<UidMap> uidMap = new UidMap();
616     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
617     sp<AlarmMonitor> anomalyAlarmMonitor;
618     sp<AlarmMonitor> periodicAlarmMonitor;
619     StatsdConfig config = buildCirclePredicates();
620     set<int> allTagIds;
621     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
622     unordered_map<int64_t, int> atomMatchingTrackerMap;
623     vector<sp<ConditionTracker>> allConditionTrackers;
624     unordered_map<int64_t, int> conditionTrackerMap;
625     vector<sp<MetricProducer>> allMetricProducers;
626     unordered_map<int64_t, int> metricProducerMap;
627     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
628     std::vector<sp<AlarmTracker>> allAlarmTrackers;
629     unordered_map<int, std::vector<int>> conditionToMetricMap;
630     unordered_map<int, std::vector<int>> trackerToMetricMap;
631     unordered_map<int, std::vector<int>> trackerToConditionMap;
632     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
633     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
634     unordered_map<int64_t, int> alertTrackerMap;
635     vector<int> metricsWithActivation;
636     map<int64_t, uint64_t> stateProtoHashes;
637     std::set<int64_t> noReportMetricIds;
638 
639     EXPECT_FALSE(initStatsdConfig(
640             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
641             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
642             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
643             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
644             trackerToConditionMap, activationAtomTrackerToMetricMap,
645             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
646             stateProtoHashes, noReportMetricIds));
647 }
648 
TEST(MetricsManagerTest,testAlertWithUnknownMetric)649 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
650     sp<UidMap> uidMap = new UidMap();
651     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
652     sp<AlarmMonitor> anomalyAlarmMonitor;
653     sp<AlarmMonitor> periodicAlarmMonitor;
654     StatsdConfig config = buildAlertWithUnknownMetric();
655     set<int> allTagIds;
656     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
657     unordered_map<int64_t, int> atomMatchingTrackerMap;
658     vector<sp<ConditionTracker>> allConditionTrackers;
659     unordered_map<int64_t, int> conditionTrackerMap;
660     vector<sp<MetricProducer>> allMetricProducers;
661     unordered_map<int64_t, int> metricProducerMap;
662     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
663     std::vector<sp<AlarmTracker>> allAlarmTrackers;
664     unordered_map<int, std::vector<int>> conditionToMetricMap;
665     unordered_map<int, std::vector<int>> trackerToMetricMap;
666     unordered_map<int, std::vector<int>> trackerToConditionMap;
667     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
668     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
669     unordered_map<int64_t, int> alertTrackerMap;
670     vector<int> metricsWithActivation;
671     map<int64_t, uint64_t> stateProtoHashes;
672     std::set<int64_t> noReportMetricIds;
673 
674     EXPECT_FALSE(initStatsdConfig(
675             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
676             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
677             allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
678             allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
679             trackerToConditionMap, activationAtomTrackerToMetricMap,
680             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
681             stateProtoHashes, noReportMetricIds));
682 }
683 
TEST(MetricsManagerTest,TestCreateAtomMatchingTrackerInvalidMatcher)684 TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerInvalidMatcher) {
685     sp<UidMap> uidMap = new UidMap();
686     AtomMatcher matcher;
687     // Matcher has no contents_case (simple/combination), so it is invalid.
688     matcher.set_id(21);
689     EXPECT_EQ(createAtomMatchingTracker(matcher, 0, uidMap), nullptr);
690 }
691 
TEST(MetricsManagerTest,TestCreateAtomMatchingTrackerSimple)692 TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerSimple) {
693     int index = 1;
694     int64_t id = 123;
695     sp<UidMap> uidMap = new UidMap();
696     AtomMatcher matcher;
697     matcher.set_id(id);
698     SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
699     simpleAtomMatcher->set_atom_id(util::SCREEN_STATE_CHANGED);
700     simpleAtomMatcher->add_field_value_matcher()->set_field(
701             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
702     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
703             android::view::DisplayStateEnum::DISPLAY_STATE_ON);
704 
705     sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(matcher, index, uidMap);
706     EXPECT_NE(tracker, nullptr);
707 
708     EXPECT_TRUE(tracker->mInitialized);
709     EXPECT_EQ(tracker->getId(), id);
710     EXPECT_EQ(tracker->mIndex, index);
711     const set<int>& atomIds = tracker->getAtomIds();
712     ASSERT_EQ(atomIds.size(), 1);
713     EXPECT_EQ(atomIds.count(util::SCREEN_STATE_CHANGED), 1);
714 }
715 
TEST(MetricsManagerTest,TestCreateAtomMatchingTrackerCombination)716 TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerCombination) {
717     int index = 1;
718     int64_t id = 123;
719     sp<UidMap> uidMap = new UidMap();
720     AtomMatcher matcher;
721     matcher.set_id(id);
722     AtomMatcher_Combination* combination = matcher.mutable_combination();
723     combination->set_operation(LogicalOperation::OR);
724     combination->add_matcher(123);
725     combination->add_matcher(223);
726 
727     sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(matcher, index, uidMap);
728     EXPECT_NE(tracker, nullptr);
729 
730     // Combination matchers need to be initialized first.
731     EXPECT_FALSE(tracker->mInitialized);
732     EXPECT_EQ(tracker->getId(), id);
733     EXPECT_EQ(tracker->mIndex, index);
734     const set<int>& atomIds = tracker->getAtomIds();
735     ASSERT_EQ(atomIds.size(), 0);
736 }
737 
TEST(MetricsManagerTest,TestCreateConditionTrackerInvalid)738 TEST(MetricsManagerTest, TestCreateConditionTrackerInvalid) {
739     const ConfigKey key(123, 456);
740     // Predicate has no contents_case (simple/combination), so it is invalid.
741     Predicate predicate;
742     predicate.set_id(21);
743     unordered_map<int64_t, int> atomTrackerMap;
744     EXPECT_EQ(createConditionTracker(key, predicate, 0, atomTrackerMap), nullptr);
745 }
746 
TEST(MetricsManagerTest,TestCreateConditionTrackerSimple)747 TEST(MetricsManagerTest, TestCreateConditionTrackerSimple) {
748     int index = 1;
749     int64_t id = 987;
750     const ConfigKey key(123, 456);
751 
752     int startMatcherIndex = 2, stopMatcherIndex = 0, stopAllMatcherIndex = 1;
753     int64_t startMatcherId = 246, stopMatcherId = 153, stopAllMatcherId = 975;
754 
755     Predicate predicate;
756     predicate.set_id(id);
757     SimplePredicate* simplePredicate = predicate.mutable_simple_predicate();
758     simplePredicate->set_start(startMatcherId);
759     simplePredicate->set_stop(stopMatcherId);
760     simplePredicate->set_stop_all(stopAllMatcherId);
761 
762     unordered_map<int64_t, int> atomTrackerMap;
763     atomTrackerMap[startMatcherId] = startMatcherIndex;
764     atomTrackerMap[stopMatcherId] = stopMatcherIndex;
765     atomTrackerMap[stopAllMatcherId] = stopAllMatcherIndex;
766 
767     sp<ConditionTracker> tracker = createConditionTracker(key, predicate, index, atomTrackerMap);
768     EXPECT_EQ(tracker->getConditionId(), id);
769     EXPECT_EQ(tracker->isSliced(), false);
770     EXPECT_TRUE(tracker->IsSimpleCondition());
771     const set<int>& interestedMatchers = tracker->getAtomMatchingTrackerIndex();
772     ASSERT_EQ(interestedMatchers.size(), 3);
773     ASSERT_EQ(interestedMatchers.count(startMatcherIndex), 1);
774     ASSERT_EQ(interestedMatchers.count(stopMatcherIndex), 1);
775     ASSERT_EQ(interestedMatchers.count(stopAllMatcherIndex), 1);
776 }
777 
TEST(MetricsManagerTest,TestCreateConditionTrackerCombination)778 TEST(MetricsManagerTest, TestCreateConditionTrackerCombination) {
779     int index = 1;
780     int64_t id = 987;
781     const ConfigKey key(123, 456);
782 
783     Predicate predicate;
784     predicate.set_id(id);
785     Predicate_Combination* combinationPredicate = predicate.mutable_combination();
786     combinationPredicate->set_operation(LogicalOperation::AND);
787     combinationPredicate->add_predicate(888);
788     combinationPredicate->add_predicate(777);
789 
790     // Combination conditions must be initialized to set most state.
791     unordered_map<int64_t, int> atomTrackerMap;
792     sp<ConditionTracker> tracker = createConditionTracker(key, predicate, index, atomTrackerMap);
793     EXPECT_EQ(tracker->getConditionId(), id);
794     EXPECT_FALSE(tracker->IsSimpleCondition());
795 }
796 
TEST(MetricsManagerTest,TestCreateAnomalyTrackerInvalidMetric)797 TEST(MetricsManagerTest, TestCreateAnomalyTrackerInvalidMetric) {
798     Alert alert;
799     alert.set_id(123);
800     alert.set_metric_id(1);
801     alert.set_trigger_if_sum_gt(1);
802     alert.set_num_buckets(1);
803 
804     sp<AlarmMonitor> anomalyAlarmMonitor;
805     vector<sp<MetricProducer>> metricProducers;
806     // Pass in empty metric producers, causing an error.
807     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123, {},
808                                    metricProducers),
809               nullopt);
810 }
811 
TEST(MetricsManagerTest,TestCreateAnomalyTrackerNoThreshold)812 TEST(MetricsManagerTest, TestCreateAnomalyTrackerNoThreshold) {
813     int64_t metricId = 1;
814     Alert alert;
815     alert.set_id(123);
816     alert.set_metric_id(metricId);
817     alert.set_num_buckets(1);
818 
819     CountMetric metric;
820     metric.set_id(metricId);
821     metric.set_bucket(ONE_MINUTE);
822     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
823     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
824             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
825     sp<AlarmMonitor> anomalyAlarmMonitor;
826     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
827                                    {{1, 0}}, metricProducers),
828               nullopt);
829 }
830 
TEST(MetricsManagerTest,TestCreateAnomalyTrackerMissingBuckets)831 TEST(MetricsManagerTest, TestCreateAnomalyTrackerMissingBuckets) {
832     int64_t metricId = 1;
833     Alert alert;
834     alert.set_id(123);
835     alert.set_metric_id(metricId);
836     alert.set_trigger_if_sum_gt(1);
837 
838     CountMetric metric;
839     metric.set_id(metricId);
840     metric.set_bucket(ONE_MINUTE);
841     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
842     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
843             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
844     sp<AlarmMonitor> anomalyAlarmMonitor;
845     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
846                                    {{1, 0}}, metricProducers),
847               nullopt);
848 }
849 
TEST(MetricsManagerTest,TestCreateAnomalyTrackerGood)850 TEST(MetricsManagerTest, TestCreateAnomalyTrackerGood) {
851     int64_t metricId = 1;
852     Alert alert;
853     alert.set_id(123);
854     alert.set_metric_id(metricId);
855     alert.set_trigger_if_sum_gt(1);
856     alert.set_num_buckets(1);
857 
858     CountMetric metric;
859     metric.set_id(metricId);
860     metric.set_bucket(ONE_MINUTE);
861     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
862     vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
863             kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
864     sp<AlarmMonitor> anomalyAlarmMonitor;
865     EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
866                                    {{1, 0}}, metricProducers),
867               nullopt);
868 }
869 
TEST(MetricsManagerTest,TestCreateAnomalyTrackerDurationTooLong)870 TEST(MetricsManagerTest, TestCreateAnomalyTrackerDurationTooLong) {
871     int64_t metricId = 1;
872     Alert alert;
873     alert.set_id(123);
874     alert.set_metric_id(metricId);
875     // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
876     alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
877     alert.set_num_buckets(1);
878 
879     DurationMetric metric;
880     metric.set_id(metricId);
881     metric.set_bucket(ONE_MINUTE);
882     metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
883     FieldMatcher dimensions;
884     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
885     vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
886             kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
887             1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
888             wizard, 0x0123456789, dimensions, 0, 0)});
889     sp<AlarmMonitor> anomalyAlarmMonitor;
890     EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
891                                    {{1, 0}}, metricProducers),
892               nullopt);
893 }
894 
TEST(MetricsManagerTest,TestCreateDurationProducerDimensionsInWhatInvalid)895 TEST(MetricsManagerTest, TestCreateDurationProducerDimensionsInWhatInvalid) {
896     StatsdConfig config;
897     config.add_allowed_log_source("AID_ROOT");
898     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
899     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
900     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
901     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
902 
903     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
904     // The predicate is dimensioning by first attribution node by uid.
905     FieldMatcher dimensions =
906             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
907     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
908     *config.add_predicate() = holdingWakelockPredicate;
909 
910     DurationMetric* durationMetric = config.add_duration_metric();
911     durationMetric->set_id(StringToId("WakelockDuration"));
912     durationMetric->set_what(holdingWakelockPredicate.id());
913     durationMetric->set_aggregation_type(DurationMetric::SUM);
914     // The metric is dimensioning by first attribution node by uid AND tag.
915     // Invalid since the predicate only dimensions by uid.
916     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
917             util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
918     durationMetric->set_bucket(FIVE_MINUTES);
919 
920     ConfigKey key(123, 987);
921     uint64_t timeNs = 456;
922     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
923     sp<AlarmMonitor> anomalyAlarmMonitor;
924     sp<AlarmMonitor> periodicAlarmMonitor;
925     sp<UidMap> uidMap;
926     sp<MetricsManager> metricsManager =
927             new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
928                                anomalyAlarmMonitor, periodicAlarmMonitor);
929     EXPECT_FALSE(metricsManager->isConfigValid());
930 }
931 
932 }  // namespace statsd
933 }  // namespace os
934 }  // namespace android
935 
936 #else
937 GTEST_LOG_(INFO) << "This test does nothing.\n";
938 #endif
939