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