1 // Copyright (C) 2017 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 <gtest/gtest.h>
16 #include <private/android_filesystem_config.h>
17 #include <stdio.h>
18 
19 #include <set>
20 #include <unordered_map>
21 #include <vector>
22 
23 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
24 #include "metrics/metrics_test_helper.h"
25 #include "src/condition/ConditionTracker.h"
26 #include "src/matchers/LogMatchingTracker.h"
27 #include "src/metrics/CountMetricProducer.h"
28 #include "src/metrics/GaugeMetricProducer.h"
29 #include "src/metrics/MetricProducer.h"
30 #include "src/metrics/ValueMetricProducer.h"
31 #include "src/metrics/metrics_manager_util.h"
32 #include "src/state/StateManager.h"
33 #include "statsd_test_util.h"
34 
35 using namespace testing;
36 using android::sp;
37 using android::os::statsd::Predicate;
38 using std::map;
39 using std::set;
40 using std::unordered_map;
41 using std::vector;
42 
43 #ifdef __ANDROID__
44 
45 namespace android {
46 namespace os {
47 namespace statsd {
48 
49 namespace {
50 const ConfigKey kConfigKey(0, 12345);
51 const long kAlertId = 3;
52 
53 const long timeBaseSec = 1000;
54 
buildGoodConfig()55 StatsdConfig buildGoodConfig() {
56     StatsdConfig config;
57     config.set_id(12345);
58 
59     AtomMatcher* eventMatcher = config.add_atom_matcher();
60     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
61 
62     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
63     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
64     simpleAtomMatcher->add_field_value_matcher()->set_field(
65             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
66     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
67             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
68 
69     eventMatcher = config.add_atom_matcher();
70     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
71 
72     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
73     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
74     simpleAtomMatcher->add_field_value_matcher()->set_field(
75             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
76     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
77             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
78 
79     eventMatcher = config.add_atom_matcher();
80     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
81 
82     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
83     combination->set_operation(LogicalOperation::OR);
84     combination->add_matcher(StringToId("SCREEN_IS_ON"));
85     combination->add_matcher(StringToId("SCREEN_IS_OFF"));
86 
87     CountMetric* metric = config.add_count_metric();
88     metric->set_id(3);
89     metric->set_what(StringToId("SCREEN_IS_ON"));
90     metric->set_bucket(ONE_MINUTE);
91     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
92     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
93 
94     config.add_no_report_metric(3);
95 
96     auto alert = config.add_alert();
97     alert->set_id(kAlertId);
98     alert->set_metric_id(3);
99     alert->set_num_buckets(10);
100     alert->set_refractory_period_secs(100);
101     alert->set_trigger_if_sum_gt(100);
102     return config;
103 }
104 
buildCircleMatchers()105 StatsdConfig buildCircleMatchers() {
106     StatsdConfig config;
107     config.set_id(12345);
108 
109     AtomMatcher* eventMatcher = config.add_atom_matcher();
110     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
111 
112     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
113     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
114     simpleAtomMatcher->add_field_value_matcher()->set_field(
115             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
116     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
117             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
118 
119     eventMatcher = config.add_atom_matcher();
120     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
121 
122     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
123     combination->set_operation(LogicalOperation::OR);
124     combination->add_matcher(StringToId("SCREEN_IS_ON"));
125     // Circle dependency
126     combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
127 
128     return config;
129 }
130 
buildAlertWithUnknownMetric()131 StatsdConfig buildAlertWithUnknownMetric() {
132     StatsdConfig config;
133     config.set_id(12345);
134 
135     AtomMatcher* eventMatcher = config.add_atom_matcher();
136     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
137 
138     CountMetric* metric = config.add_count_metric();
139     metric->set_id(3);
140     metric->set_what(StringToId("SCREEN_IS_ON"));
141     metric->set_bucket(ONE_MINUTE);
142     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
143     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
144 
145     auto alert = config.add_alert();
146     alert->set_id(3);
147     alert->set_metric_id(2);
148     alert->set_num_buckets(10);
149     alert->set_refractory_period_secs(100);
150     alert->set_trigger_if_sum_gt(100);
151     return config;
152 }
153 
buildMissingMatchers()154 StatsdConfig buildMissingMatchers() {
155     StatsdConfig config;
156     config.set_id(12345);
157 
158     AtomMatcher* eventMatcher = config.add_atom_matcher();
159     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
160 
161     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
162     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
163     simpleAtomMatcher->add_field_value_matcher()->set_field(
164             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
165     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
166             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
167 
168     eventMatcher = config.add_atom_matcher();
169     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
170 
171     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
172     combination->set_operation(LogicalOperation::OR);
173     combination->add_matcher(StringToId("SCREEN_IS_ON"));
174     // undefined matcher
175     combination->add_matcher(StringToId("ABC"));
176 
177     return config;
178 }
179 
buildMissingPredicate()180 StatsdConfig buildMissingPredicate() {
181     StatsdConfig config;
182     config.set_id(12345);
183 
184     CountMetric* metric = config.add_count_metric();
185     metric->set_id(3);
186     metric->set_what(StringToId("SCREEN_EVENT"));
187     metric->set_bucket(ONE_MINUTE);
188     metric->set_condition(StringToId("SOME_CONDITION"));
189 
190     AtomMatcher* eventMatcher = config.add_atom_matcher();
191     eventMatcher->set_id(StringToId("SCREEN_EVENT"));
192 
193     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
194     simpleAtomMatcher->set_atom_id(2);
195 
196     return config;
197 }
198 
buildDimensionMetricsWithMultiTags()199 StatsdConfig buildDimensionMetricsWithMultiTags() {
200     StatsdConfig config;
201     config.set_id(12345);
202 
203     AtomMatcher* eventMatcher = config.add_atom_matcher();
204     eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
205     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
206     simpleAtomMatcher->set_atom_id(2);
207 
208     eventMatcher = config.add_atom_matcher();
209     eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
210     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
211     simpleAtomMatcher->set_atom_id(3);
212 
213     eventMatcher = config.add_atom_matcher();
214     eventMatcher->set_id(StringToId("BATTERY_LOW"));
215 
216     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
217     combination->set_operation(LogicalOperation::OR);
218     combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
219     combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
220 
221     // Count process state changes, slice by uid, while SCREEN_IS_OFF
222     CountMetric* metric = config.add_count_metric();
223     metric->set_id(3);
224     metric->set_what(StringToId("BATTERY_LOW"));
225     metric->set_bucket(ONE_MINUTE);
226     // This case is interesting. We want to dimension across two atoms.
227     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
228 
229     auto alert = config.add_alert();
230     alert->set_id(kAlertId);
231     alert->set_metric_id(3);
232     alert->set_num_buckets(10);
233     alert->set_refractory_period_secs(100);
234     alert->set_trigger_if_sum_gt(100);
235     return config;
236 }
237 
buildCirclePredicates()238 StatsdConfig buildCirclePredicates() {
239     StatsdConfig config;
240     config.set_id(12345);
241 
242     AtomMatcher* eventMatcher = config.add_atom_matcher();
243     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
244 
245     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
246     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
247     simpleAtomMatcher->add_field_value_matcher()->set_field(
248             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
249     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
250             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
251 
252     eventMatcher = config.add_atom_matcher();
253     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
254 
255     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
256     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
257     simpleAtomMatcher->add_field_value_matcher()->set_field(
258             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
259     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
260             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
261 
262     auto condition = config.add_predicate();
263     condition->set_id(StringToId("SCREEN_IS_ON"));
264     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
265     simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
266     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
267 
268     condition = config.add_predicate();
269     condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
270 
271     Predicate_Combination* combination = condition->mutable_combination();
272     combination->set_operation(LogicalOperation::OR);
273     combination->add_predicate(StringToId("SCREEN_IS_ON"));
274     combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
275 
276     return config;
277 }
278 
buildConfigWithDifferentPredicates()279 StatsdConfig buildConfigWithDifferentPredicates() {
280     StatsdConfig config;
281     config.set_id(12345);
282 
283     auto pulledAtomMatcher =
284             CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
285     *config.add_atom_matcher() = pulledAtomMatcher;
286     auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
287     *config.add_atom_matcher() = screenOnAtomMatcher;
288     auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
289     *config.add_atom_matcher() = screenOffAtomMatcher;
290     auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
291     *config.add_atom_matcher() = batteryNoneAtomMatcher;
292     auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
293     *config.add_atom_matcher() = batteryUsbAtomMatcher;
294 
295     // Simple condition with InitialValue set to default (unknown).
296     auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
297     *config.add_predicate() = screenOnUnknownPredicate;
298 
299     // Simple condition with InitialValue set to false.
300     auto screenOnFalsePredicate = config.add_predicate();
301     screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
302     SimplePredicate* simpleScreenOnFalsePredicate =
303             screenOnFalsePredicate->mutable_simple_predicate();
304     simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
305     simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
306     simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
307 
308     // Simple condition with InitialValue set to false.
309     auto onBatteryFalsePredicate = config.add_predicate();
310     onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
311     SimplePredicate* simpleOnBatteryFalsePredicate =
312             onBatteryFalsePredicate->mutable_simple_predicate();
313     simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
314     simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
315     simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
316 
317     // Combination condition with both simple condition InitialValues set to false.
318     auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
319     screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
320     screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
321             LogicalOperation::AND);
322     addPredicateToPredicateCombination(*screenOnFalsePredicate,
323                                        screenOnFalseOnBatteryFalsePredicate);
324     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
325                                        screenOnFalseOnBatteryFalsePredicate);
326 
327     // Combination condition with one simple condition InitialValue set to unknown and one set to
328     // false.
329     auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
330     screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
331     screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
332             LogicalOperation::AND);
333     addPredicateToPredicateCombination(screenOnUnknownPredicate,
334                                        screenOnUnknownOnBatteryFalsePredicate);
335     addPredicateToPredicateCombination(*onBatteryFalsePredicate,
336                                        screenOnUnknownOnBatteryFalsePredicate);
337 
338     // Simple condition metric with initial value false.
339     ValueMetric* metric1 = config.add_value_metric();
340     metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
341     metric1->set_what(pulledAtomMatcher.id());
342     *metric1->mutable_value_field() =
343             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
344     metric1->set_bucket(FIVE_MINUTES);
345     metric1->set_condition(screenOnFalsePredicate->id());
346 
347     // Simple condition metric with initial value unknown.
348     ValueMetric* metric2 = config.add_value_metric();
349     metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
350     metric2->set_what(pulledAtomMatcher.id());
351     *metric2->mutable_value_field() =
352             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
353     metric2->set_bucket(FIVE_MINUTES);
354     metric2->set_condition(screenOnUnknownPredicate.id());
355 
356     // Combination condition metric with initial values false and false.
357     ValueMetric* metric3 = config.add_value_metric();
358     metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
359     metric3->set_what(pulledAtomMatcher.id());
360     *metric3->mutable_value_field() =
361             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
362     metric3->set_bucket(FIVE_MINUTES);
363     metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
364 
365     // Combination condition metric with initial values unknown and false.
366     ValueMetric* metric4 = config.add_value_metric();
367     metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
368     metric4->set_what(pulledAtomMatcher.id());
369     *metric4->mutable_value_field() =
370             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
371     metric4->set_bucket(FIVE_MINUTES);
372     metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
373 
374     return config;
375 }
376 
isSubset(const set<int32_t> & set1,const set<int32_t> & set2)377 bool isSubset(const set<int32_t>& set1, const set<int32_t>& set2) {
378     return std::includes(set2.begin(), set2.end(), set1.begin(), set1.end());
379 }
380 }  // anonymous namespace
381 
TEST(MetricsManagerTest,TestInitialConditions)382 TEST(MetricsManagerTest, TestInitialConditions) {
383     UidMap uidMap;
384     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
385     sp<AlarmMonitor> anomalyAlarmMonitor;
386     sp<AlarmMonitor> periodicAlarmMonitor;
387     StatsdConfig config = buildConfigWithDifferentPredicates();
388     set<int> allTagIds;
389     vector<sp<LogMatchingTracker>> allAtomMatchers;
390     vector<sp<ConditionTracker>> allConditionTrackers;
391     vector<sp<MetricProducer>> allMetricProducers;
392     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
393     std::vector<sp<AlarmTracker>> allAlarmTrackers;
394     unordered_map<int, std::vector<int>> conditionToMetricMap;
395     unordered_map<int, std::vector<int>> trackerToMetricMap;
396     unordered_map<int, std::vector<int>> trackerToConditionMap;
397     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
398     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
399     unordered_map<int64_t, int> alertTrackerMap;
400     vector<int> metricsWithActivation;
401     std::set<int64_t> noReportMetricIds;
402 
403     EXPECT_TRUE(initStatsdConfig(
404             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
405             timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, allConditionTrackers,
406             allMetricProducers, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
407             trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
408             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
409             noReportMetricIds));
410     ASSERT_EQ(4u, allMetricProducers.size());
411     ASSERT_EQ(5u, allConditionTrackers.size());
412 
413     ConditionKey queryKey;
414     vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
415 
416     allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
417     allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
418     EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
419     EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
420     EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
421     EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
422     EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
423 
424     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
425     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
426     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
427     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
428 }
429 
TEST(MetricsManagerTest,TestGoodConfig)430 TEST(MetricsManagerTest, TestGoodConfig) {
431     UidMap uidMap;
432     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
433     sp<AlarmMonitor> anomalyAlarmMonitor;
434     sp<AlarmMonitor> periodicAlarmMonitor;
435     StatsdConfig config = buildGoodConfig();
436     set<int> allTagIds;
437     vector<sp<LogMatchingTracker>> allAtomMatchers;
438     vector<sp<ConditionTracker>> allConditionTrackers;
439     vector<sp<MetricProducer>> allMetricProducers;
440     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
441     std::vector<sp<AlarmTracker>> allAlarmTrackers;
442     unordered_map<int, std::vector<int>> conditionToMetricMap;
443     unordered_map<int, std::vector<int>> trackerToMetricMap;
444     unordered_map<int, std::vector<int>> trackerToConditionMap;
445     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
446     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
447     unordered_map<int64_t, int> alertTrackerMap;
448     vector<int> metricsWithActivation;
449     std::set<int64_t> noReportMetricIds;
450 
451     EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
452                                  periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
453                                  allAtomMatchers, allConditionTrackers, allMetricProducers,
454                                  allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
455                                  trackerToMetricMap, trackerToConditionMap,
456                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
457                                  alertTrackerMap, metricsWithActivation,
458                                  noReportMetricIds));
459     ASSERT_EQ(1u, allMetricProducers.size());
460     ASSERT_EQ(1u, allAnomalyTrackers.size());
461     ASSERT_EQ(1u, noReportMetricIds.size());
462     ASSERT_EQ(1u, alertTrackerMap.size());
463     EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
464     EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
465 }
466 
TEST(MetricsManagerTest,TestDimensionMetricsWithMultiTags)467 TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
468     UidMap uidMap;
469     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
470     sp<AlarmMonitor> anomalyAlarmMonitor;
471     sp<AlarmMonitor> periodicAlarmMonitor;
472     StatsdConfig config = buildDimensionMetricsWithMultiTags();
473     set<int> allTagIds;
474     vector<sp<LogMatchingTracker>> allAtomMatchers;
475     vector<sp<ConditionTracker>> allConditionTrackers;
476     vector<sp<MetricProducer>> allMetricProducers;
477     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
478     std::vector<sp<AlarmTracker>> allAlarmTrackers;
479     unordered_map<int, std::vector<int>> conditionToMetricMap;
480     unordered_map<int, std::vector<int>> trackerToMetricMap;
481     unordered_map<int, std::vector<int>> trackerToConditionMap;
482     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
483     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
484     unordered_map<int64_t, int> alertTrackerMap;
485     vector<int> metricsWithActivation;
486     std::set<int64_t> noReportMetricIds;
487 
488     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
489                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
490                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
491                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
492                                   trackerToMetricMap, trackerToConditionMap,
493                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
494                                   alertTrackerMap, metricsWithActivation,
495                                   noReportMetricIds));
496 }
497 
TEST(MetricsManagerTest,TestCircleLogMatcherDependency)498 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
499     UidMap uidMap;
500     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
501     sp<AlarmMonitor> anomalyAlarmMonitor;
502     sp<AlarmMonitor> periodicAlarmMonitor;
503     StatsdConfig config = buildCircleMatchers();
504     set<int> allTagIds;
505     vector<sp<LogMatchingTracker>> allAtomMatchers;
506     vector<sp<ConditionTracker>> allConditionTrackers;
507     vector<sp<MetricProducer>> allMetricProducers;
508     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
509     std::vector<sp<AlarmTracker>> allAlarmTrackers;
510     unordered_map<int, std::vector<int>> conditionToMetricMap;
511     unordered_map<int, std::vector<int>> trackerToMetricMap;
512     unordered_map<int, std::vector<int>> trackerToConditionMap;
513     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
514     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
515     unordered_map<int64_t, int> alertTrackerMap;
516     vector<int> metricsWithActivation;
517     std::set<int64_t> noReportMetricIds;
518 
519     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
520                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
521                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
522                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
523                                   trackerToMetricMap, trackerToConditionMap,
524                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
525                                   alertTrackerMap, metricsWithActivation,
526                                   noReportMetricIds));
527 }
528 
TEST(MetricsManagerTest,TestMissingMatchers)529 TEST(MetricsManagerTest, TestMissingMatchers) {
530     UidMap uidMap;
531     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
532     sp<AlarmMonitor> anomalyAlarmMonitor;
533     sp<AlarmMonitor> periodicAlarmMonitor;
534     StatsdConfig config = buildMissingMatchers();
535     set<int> allTagIds;
536     vector<sp<LogMatchingTracker>> allAtomMatchers;
537     vector<sp<ConditionTracker>> allConditionTrackers;
538     vector<sp<MetricProducer>> allMetricProducers;
539     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
540     std::vector<sp<AlarmTracker>> allAlarmTrackers;
541     unordered_map<int, std::vector<int>> conditionToMetricMap;
542     unordered_map<int, std::vector<int>> trackerToMetricMap;
543     unordered_map<int, std::vector<int>> trackerToConditionMap;
544     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
545     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
546     unordered_map<int64_t, int> alertTrackerMap;
547     vector<int> metricsWithActivation;
548     std::set<int64_t> noReportMetricIds;
549     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
550                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
551                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
552                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
553                                   trackerToMetricMap, trackerToConditionMap,
554                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
555                                   alertTrackerMap, metricsWithActivation,
556                                   noReportMetricIds));
557 }
558 
TEST(MetricsManagerTest,TestMissingPredicate)559 TEST(MetricsManagerTest, TestMissingPredicate) {
560     UidMap uidMap;
561     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
562     sp<AlarmMonitor> anomalyAlarmMonitor;
563     sp<AlarmMonitor> periodicAlarmMonitor;
564     StatsdConfig config = buildMissingPredicate();
565     set<int> allTagIds;
566     vector<sp<LogMatchingTracker>> allAtomMatchers;
567     vector<sp<ConditionTracker>> allConditionTrackers;
568     vector<sp<MetricProducer>> allMetricProducers;
569     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
570     std::vector<sp<AlarmTracker>> allAlarmTrackers;
571     unordered_map<int, std::vector<int>> conditionToMetricMap;
572     unordered_map<int, std::vector<int>> trackerToMetricMap;
573     unordered_map<int, std::vector<int>> trackerToConditionMap;
574     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
575     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
576     unordered_map<int64_t, int> alertTrackerMap;
577     vector<int> metricsWithActivation;
578     std::set<int64_t> noReportMetricIds;
579     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
580                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
581                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
582                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
583                                   trackerToMetricMap, trackerToConditionMap,
584                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
585                                   alertTrackerMap, metricsWithActivation, noReportMetricIds));
586 }
587 
TEST(MetricsManagerTest,TestCirclePredicateDependency)588 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
589     UidMap uidMap;
590     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
591     sp<AlarmMonitor> anomalyAlarmMonitor;
592     sp<AlarmMonitor> periodicAlarmMonitor;
593     StatsdConfig config = buildCirclePredicates();
594     set<int> allTagIds;
595     vector<sp<LogMatchingTracker>> allAtomMatchers;
596     vector<sp<ConditionTracker>> allConditionTrackers;
597     vector<sp<MetricProducer>> allMetricProducers;
598     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
599     std::vector<sp<AlarmTracker>> allAlarmTrackers;
600     unordered_map<int, std::vector<int>> conditionToMetricMap;
601     unordered_map<int, std::vector<int>> trackerToMetricMap;
602     unordered_map<int, std::vector<int>> trackerToConditionMap;
603     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
604     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
605     unordered_map<int64_t, int> alertTrackerMap;
606     vector<int> metricsWithActivation;
607     std::set<int64_t> noReportMetricIds;
608 
609     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
610                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
611                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
612                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
613                                   trackerToMetricMap, trackerToConditionMap,
614                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
615                                   alertTrackerMap, metricsWithActivation,
616                                   noReportMetricIds));
617 }
618 
TEST(MetricsManagerTest,testAlertWithUnknownMetric)619 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
620     UidMap uidMap;
621     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
622     sp<AlarmMonitor> anomalyAlarmMonitor;
623     sp<AlarmMonitor> periodicAlarmMonitor;
624     StatsdConfig config = buildAlertWithUnknownMetric();
625     set<int> allTagIds;
626     vector<sp<LogMatchingTracker>> allAtomMatchers;
627     vector<sp<ConditionTracker>> allConditionTrackers;
628     vector<sp<MetricProducer>> allMetricProducers;
629     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
630     std::vector<sp<AlarmTracker>> allAlarmTrackers;
631     unordered_map<int, std::vector<int>> conditionToMetricMap;
632     unordered_map<int, std::vector<int>> trackerToMetricMap;
633     unordered_map<int, std::vector<int>> trackerToConditionMap;
634     unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
635     unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
636     unordered_map<int64_t, int> alertTrackerMap;
637     vector<int> metricsWithActivation;
638     std::set<int64_t> noReportMetricIds;
639 
640     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
641                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
642                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
643                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
644                                   trackerToMetricMap, trackerToConditionMap,
645                                   activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
646                                   alertTrackerMap, metricsWithActivation,
647                                   noReportMetricIds));
648 }
649 
TEST(MetricsManagerTest,TestLogSources)650 TEST(MetricsManagerTest, TestLogSources) {
651     string app1 = "app1";
652     set<int32_t> app1Uids = {1111, 11111};
653     string app2 = "app2";
654     set<int32_t> app2Uids = {2222};
655     string app3 = "app3";
656     set<int32_t> app3Uids = {3333, 1111};
657 
658     map<string, set<int32_t>> pkgToUids;
659     pkgToUids[app1] = app1Uids;
660     pkgToUids[app2] = app2Uids;
661     pkgToUids[app3] = app3Uids;
662 
663     int32_t atom1 = 10;
664     int32_t atom2 = 20;
665     int32_t atom3 = 30;
666     sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
667     EXPECT_CALL(*uidMap, getAppUid(_))
668             .Times(4)
669             .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
670                 const auto& it = pkgToUids.find(pkg);
671                 if (it != pkgToUids.end()) {
672                     return it->second;
673                 }
674                 return set<int32_t>();
675             }));
676     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
677     EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
678     EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
679 
680     sp<AlarmMonitor> anomalyAlarmMonitor;
681     sp<AlarmMonitor> periodicAlarmMonitor;
682 
683     StatsdConfig config = buildGoodConfig();
684     config.add_allowed_log_source("AID_SYSTEM");
685     config.add_allowed_log_source(app1);
686     config.add_default_pull_packages("AID_SYSTEM");
687     config.add_default_pull_packages("AID_ROOT");
688 
689     const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_ROOT};
690 
691     PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
692     pullAtomPackages->set_atom_id(atom1);
693     pullAtomPackages->add_packages(app1);
694     pullAtomPackages->add_packages(app3);
695 
696     pullAtomPackages = config.add_pull_atom_packages();
697     pullAtomPackages->set_atom_id(atom2);
698     pullAtomPackages->add_packages(app2);
699     pullAtomPackages->add_packages("AID_STATSD");
700 
701     MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
702                                   pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
703 
704     EXPECT_TRUE(metricsManager.isConfigValid());
705 
706     ASSERT_EQ(metricsManager.mAllowedUid.size(), 1);
707     EXPECT_EQ(metricsManager.mAllowedUid[0], AID_SYSTEM);
708 
709     ASSERT_EQ(metricsManager.mAllowedPkg.size(), 1);
710     EXPECT_EQ(metricsManager.mAllowedPkg[0], app1);
711 
712     ASSERT_EQ(metricsManager.mAllowedLogSources.size(), 3);
713     EXPECT_TRUE(isSubset({AID_SYSTEM}, metricsManager.mAllowedLogSources));
714     EXPECT_TRUE(isSubset(app1Uids, metricsManager.mAllowedLogSources));
715 
716     ASSERT_EQ(metricsManager.mDefaultPullUids.size(), 2);
717     EXPECT_TRUE(isSubset(defaultPullUids, metricsManager.mDefaultPullUids));
718     ;
719 
720     vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
721     ASSERT_EQ(atom1Uids.size(), 5);
722     set<int32_t> expectedAtom1Uids;
723     expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
724     expectedAtom1Uids.insert(app1Uids.begin(), app1Uids.end());
725     expectedAtom1Uids.insert(app3Uids.begin(), app3Uids.end());
726     EXPECT_TRUE(isSubset(expectedAtom1Uids, set<int32_t>(atom1Uids.begin(), atom1Uids.end())));
727 
728     vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
729     ASSERT_EQ(atom2Uids.size(), 4);
730     set<int32_t> expectedAtom2Uids;
731     expectedAtom1Uids.insert(defaultPullUids.begin(), defaultPullUids.end());
732     expectedAtom1Uids.insert(app2Uids.begin(), app2Uids.end());
733     expectedAtom1Uids.insert(AID_STATSD);
734     EXPECT_TRUE(isSubset(expectedAtom2Uids, set<int32_t>(atom2Uids.begin(), atom2Uids.end())));
735 
736     vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
737     ASSERT_EQ(atom3Uids.size(), 2);
738     EXPECT_TRUE(isSubset(defaultPullUids, set<int32_t>(atom3Uids.begin(), atom3Uids.end())));
739 }
740 
TEST(MetricsManagerTest,TestCheckLogCredentialsWhitelistedAtom)741 TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
742     sp<UidMap> uidMap;
743     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
744     sp<AlarmMonitor> anomalyAlarmMonitor;
745     sp<AlarmMonitor> periodicAlarmMonitor;
746 
747     StatsdConfig config = buildGoodConfig();
748     config.add_whitelisted_atom_ids(3);
749     config.add_whitelisted_atom_ids(4);
750 
751     MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
752                                   pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
753 
754     LogEvent event(0 /* uid */, 0 /* pid */);
755     CreateNoValuesLogEvent(&event, 10 /* atom id */, 0 /* timestamp */);
756     EXPECT_FALSE(metricsManager.checkLogCredentials(event));
757 
758     CreateNoValuesLogEvent(&event, 3 /* atom id */, 0 /* timestamp */);
759     EXPECT_TRUE(metricsManager.checkLogCredentials(event));
760 
761     CreateNoValuesLogEvent(&event, 4 /* atom id */, 0 /* timestamp */);
762     EXPECT_TRUE(metricsManager.checkLogCredentials(event));
763 }
764 
TEST(MetricsManagerTest,TestWhitelistedAtomStateTracker)765 TEST(MetricsManagerTest, TestWhitelistedAtomStateTracker) {
766     sp<UidMap> uidMap;
767     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
768     sp<AlarmMonitor> anomalyAlarmMonitor;
769     sp<AlarmMonitor> periodicAlarmMonitor;
770 
771     StatsdConfig config = buildGoodConfig();
772     config.add_allowed_log_source("AID_SYSTEM");
773     config.add_whitelisted_atom_ids(3);
774     config.add_whitelisted_atom_ids(4);
775 
776     State state;
777     state.set_id(1);
778     state.set_atom_id(3);
779 
780     *config.add_state() = state;
781 
782     config.mutable_count_metric(0)->add_slice_by_state(state.id());
783 
784     StateManager::getInstance().clear();
785 
786     MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
787                                   pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
788 
789     EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
790     EXPECT_FALSE(metricsManager.isConfigValid());
791 }
792 
793 }  // namespace statsd
794 }  // namespace os
795 }  // namespace android
796 
797 #else
798 GTEST_LOG_(INFO) << "This test does nothing.\n";
799 #endif
800