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