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