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 <numeric>
23 #include <set>
24 #include <unordered_map>
25 #include <vector>
26
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/KllMetricProducer.h"
33 #include "src/metrics/MetricProducer.h"
34 #include "src/metrics/NumericValueMetricProducer.h"
35 #include "src/state/StateManager.h"
36 #include "src/statsd_config.pb.h"
37 #include "tests/metrics/metrics_test_helper.h"
38 #include "tests/metrics/parsing_utils/parsing_test_utils.h"
39 #include "tests/statsd_test_util.h"
40
41 using namespace testing;
42 using android::sp;
43 using android::os::statsd::Predicate;
44 using std::map;
45 using std::set;
46 using std::unordered_map;
47 using std::vector;
48
49 #ifdef __ANDROID__
50
51 namespace android {
52 namespace os {
53 namespace statsd {
54
55 namespace {
56
buildCircleMatchers()57 StatsdConfig buildCircleMatchers() {
58 StatsdConfig config;
59 config.set_id(12345);
60
61 AtomMatcher* eventMatcher = config.add_atom_matcher();
62 eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
63
64 SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
65 simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
66 simpleAtomMatcher->add_field_value_matcher()->set_field(
67 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
68 simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
69 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
70
71 eventMatcher = config.add_atom_matcher();
72 eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
73
74 AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
75 combination->set_operation(LogicalOperation::OR);
76 combination->add_matcher(StringToId("SCREEN_IS_ON"));
77 // Circle dependency
78 combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
79
80 return config;
81 }
82
buildAlertWithUnknownMetric()83 StatsdConfig buildAlertWithUnknownMetric() {
84 StatsdConfig config;
85 config.set_id(12345);
86
87 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
88
89 CountMetric* metric = config.add_count_metric();
90 metric->set_id(3);
91 metric->set_what(StringToId("ScreenTurnedOn"));
92 metric->set_bucket(ONE_MINUTE);
93 metric->mutable_dimensions_in_what()->set_field(SCREEN_STATE_ATOM_ID);
94 metric->mutable_dimensions_in_what()->add_child()->set_field(1);
95
96 auto alert = config.add_alert();
97 alert->set_id(3);
98 alert->set_metric_id(2);
99 alert->set_num_buckets(10);
100 alert->set_refractory_period_secs(100);
101 alert->set_trigger_if_sum_gt(100);
102 return config;
103 }
104
buildMissingMatchers()105 StatsdConfig buildMissingMatchers() {
106 StatsdConfig config;
107 config.set_id(12345);
108
109 AtomMatcher* eventMatcher = config.add_atom_matcher();
110 eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
111
112 SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
113 simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
114 simpleAtomMatcher->add_field_value_matcher()->set_field(
115 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
116 simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
117 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
118
119 eventMatcher = config.add_atom_matcher();
120 eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
121
122 AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
123 combination->set_operation(LogicalOperation::OR);
124 combination->add_matcher(StringToId("SCREEN_IS_ON"));
125 // undefined matcher
126 combination->add_matcher(StringToId("ABC"));
127
128 return config;
129 }
130
buildMissingPredicate()131 StatsdConfig buildMissingPredicate() {
132 StatsdConfig config;
133 config.set_id(12345);
134
135 CountMetric* metric = config.add_count_metric();
136 metric->set_id(3);
137 metric->set_what(StringToId("SCREEN_EVENT"));
138 metric->set_bucket(ONE_MINUTE);
139 metric->set_condition(StringToId("SOME_CONDITION"));
140
141 AtomMatcher* eventMatcher = config.add_atom_matcher();
142 eventMatcher->set_id(StringToId("SCREEN_EVENT"));
143
144 SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
145 simpleAtomMatcher->set_atom_id(2);
146
147 return config;
148 }
149
buildDimensionMetricsWithMultiTags()150 StatsdConfig buildDimensionMetricsWithMultiTags() {
151 StatsdConfig config;
152 config.set_id(12345);
153
154 AtomMatcher* eventMatcher = config.add_atom_matcher();
155 eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
156 SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
157 simpleAtomMatcher->set_atom_id(2);
158
159 eventMatcher = config.add_atom_matcher();
160 eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
161 simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
162 simpleAtomMatcher->set_atom_id(3);
163
164 eventMatcher = config.add_atom_matcher();
165 eventMatcher->set_id(StringToId("BATTERY_LOW"));
166
167 AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
168 combination->set_operation(LogicalOperation::OR);
169 combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
170 combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
171
172 // Count process state changes, slice by uid, while SCREEN_IS_OFF
173 CountMetric* metric = config.add_count_metric();
174 metric->set_id(3);
175 metric->set_what(StringToId("BATTERY_LOW"));
176 metric->set_bucket(ONE_MINUTE);
177 // This case is interesting. We want to dimension across two atoms.
178 metric->mutable_dimensions_in_what()->add_child()->set_field(1);
179
180 auto alert = config.add_alert();
181 alert->set_id(kAlertId);
182 alert->set_metric_id(3);
183 alert->set_num_buckets(10);
184 alert->set_refractory_period_secs(100);
185 alert->set_trigger_if_sum_gt(100);
186 return config;
187 }
188
buildCirclePredicates()189 StatsdConfig buildCirclePredicates() {
190 StatsdConfig config;
191 config.set_id(12345);
192
193 AtomMatcher* eventMatcher = config.add_atom_matcher();
194 eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
195
196 SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
197 simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
198 simpleAtomMatcher->add_field_value_matcher()->set_field(
199 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
200 simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
201 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
202
203 eventMatcher = config.add_atom_matcher();
204 eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
205
206 simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
207 simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
208 simpleAtomMatcher->add_field_value_matcher()->set_field(
209 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
210 simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
211 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
212
213 auto condition = config.add_predicate();
214 condition->set_id(StringToId("SCREEN_IS_ON"));
215 SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
216 simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
217 simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
218
219 condition = config.add_predicate();
220 condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
221
222 Predicate_Combination* combination = condition->mutable_combination();
223 combination->set_operation(LogicalOperation::OR);
224 combination->add_predicate(StringToId("SCREEN_IS_ON"));
225 combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
226
227 return config;
228 }
229
buildConfigWithDifferentPredicates()230 StatsdConfig buildConfigWithDifferentPredicates() {
231 StatsdConfig config;
232 config.set_id(12345);
233
234 auto pulledAtomMatcher =
235 CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
236 *config.add_atom_matcher() = pulledAtomMatcher;
237 auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
238 *config.add_atom_matcher() = screenOnAtomMatcher;
239 auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
240 *config.add_atom_matcher() = screenOffAtomMatcher;
241 auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
242 *config.add_atom_matcher() = batteryNoneAtomMatcher;
243 auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
244 *config.add_atom_matcher() = batteryUsbAtomMatcher;
245
246 // Simple condition with InitialValue set to default (unknown).
247 auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
248 *config.add_predicate() = screenOnUnknownPredicate;
249
250 // Simple condition with InitialValue set to false.
251 auto screenOnFalsePredicate = config.add_predicate();
252 screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
253 SimplePredicate* simpleScreenOnFalsePredicate =
254 screenOnFalsePredicate->mutable_simple_predicate();
255 simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
256 simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
257 simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
258
259 // Simple condition with InitialValue set to false.
260 auto onBatteryFalsePredicate = config.add_predicate();
261 onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
262 SimplePredicate* simpleOnBatteryFalsePredicate =
263 onBatteryFalsePredicate->mutable_simple_predicate();
264 simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
265 simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
266 simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
267
268 // Combination condition with both simple condition InitialValues set to false.
269 auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
270 screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
271 screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
272 LogicalOperation::AND);
273 addPredicateToPredicateCombination(*screenOnFalsePredicate,
274 screenOnFalseOnBatteryFalsePredicate);
275 addPredicateToPredicateCombination(*onBatteryFalsePredicate,
276 screenOnFalseOnBatteryFalsePredicate);
277
278 // Combination condition with one simple condition InitialValue set to unknown and one set to
279 // false.
280 auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
281 screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
282 screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
283 LogicalOperation::AND);
284 addPredicateToPredicateCombination(screenOnUnknownPredicate,
285 screenOnUnknownOnBatteryFalsePredicate);
286 addPredicateToPredicateCombination(*onBatteryFalsePredicate,
287 screenOnUnknownOnBatteryFalsePredicate);
288
289 // Simple condition metric with initial value false.
290 ValueMetric* metric1 = config.add_value_metric();
291 metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
292 metric1->set_what(pulledAtomMatcher.id());
293 *metric1->mutable_value_field() =
294 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
295 metric1->set_bucket(FIVE_MINUTES);
296 metric1->set_condition(screenOnFalsePredicate->id());
297
298 // Simple condition metric with initial value unknown.
299 ValueMetric* metric2 = config.add_value_metric();
300 metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
301 metric2->set_what(pulledAtomMatcher.id());
302 *metric2->mutable_value_field() =
303 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
304 metric2->set_bucket(FIVE_MINUTES);
305 metric2->set_condition(screenOnUnknownPredicate.id());
306
307 // Combination condition metric with initial values false and false.
308 ValueMetric* metric3 = config.add_value_metric();
309 metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
310 metric3->set_what(pulledAtomMatcher.id());
311 *metric3->mutable_value_field() =
312 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
313 metric3->set_bucket(FIVE_MINUTES);
314 metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
315
316 // Combination condition metric with initial values unknown and false.
317 ValueMetric* metric4 = config.add_value_metric();
318 metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
319 metric4->set_what(pulledAtomMatcher.id());
320 *metric4->mutable_value_field() =
321 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
322 metric4->set_bucket(FIVE_MINUTES);
323 metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
324
325 return config;
326 }
327
328 using MetricsManagerUtilTest = InitConfigTest;
329
330 struct DimLimitTestCase {
331 int configLimit;
332 int actualLimit;
333
PrintTo(const DimLimitTestCase & testCase,ostream * os)334 friend void PrintTo(const DimLimitTestCase& testCase, ostream* os) {
335 *os << testCase.configLimit;
336 }
337 };
338
339 class MetricsManagerUtilDimLimitTest : public MetricsManagerUtilTest,
340 public WithParamInterface<DimLimitTestCase> {};
341
342 const vector<DimLimitTestCase> dimLimitTestCases = {{900, 900}, {799, 800}, {3001, 3000}, {0, 800}};
343
344 INSTANTIATE_TEST_SUITE_P(DimLimit, MetricsManagerUtilDimLimitTest, ValuesIn(dimLimitTestCases),
345 PrintToStringParamName());
346
347 } // anonymous namespace
348
TEST_F(MetricsManagerUtilTest,TestInitialConditions)349 TEST_F(MetricsManagerUtilTest, TestInitialConditions) {
350 // initConfig returns nullopt if config is valid
351 EXPECT_EQ(initConfig(buildConfigWithDifferentPredicates()), nullopt);
352 ASSERT_EQ(4u, allMetricProducers.size());
353 ASSERT_EQ(5u, allConditionTrackers.size());
354
355 ConditionKey queryKey;
356 vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
357
358 allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
359 allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
360 EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
361 EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
362 EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
363 EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
364 EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
365
366 EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
367 EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
368 EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
369 EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
370
371 EXPECT_EQ(allTagIdsToMatchersMap.size(), 3);
372 EXPECT_EQ(allTagIdsToMatchersMap[SCREEN_STATE_ATOM_ID].size(), 2);
373 EXPECT_EQ(allTagIdsToMatchersMap[util::PLUGGED_STATE_CHANGED].size(), 2);
374 EXPECT_EQ(allTagIdsToMatchersMap[util::SUBSYSTEM_SLEEP_STATE].size(), 1);
375 }
376
TEST_F(MetricsManagerUtilTest,TestGoodConfig)377 TEST_F(MetricsManagerUtilTest, TestGoodConfig) {
378 StatsdConfig config = buildGoodConfig(kConfigId, kAlertId);
379 // initConfig returns nullopt if config is valid
380 EXPECT_EQ(initConfig(config), nullopt);
381 ASSERT_EQ(5u, allMetricProducers.size());
382 EXPECT_THAT(metricProducerMap, UnorderedElementsAre(Key(config.count_metric(0).id()),
383 Key(config.duration_metric(0).id()),
384 Key(config.value_metric(0).id()),
385 Key(config.kll_metric(0).id()),
386 Key(config.gauge_metric(0).id())));
387 ASSERT_EQ(1u, allAnomalyTrackers.size());
388 ASSERT_EQ(1u, noReportMetricIds.size());
389 ASSERT_EQ(1u, alertTrackerMap.size());
390 EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
391 EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
392 }
393
TEST_F(MetricsManagerUtilTest,TestDimensionMetricsWithMultiTags)394 TEST_F(MetricsManagerUtilTest, TestDimensionMetricsWithMultiTags) {
395 EXPECT_EQ(initConfig(buildDimensionMetricsWithMultiTags()),
396 createInvalidConfigReasonWithMatcher(
397 INVALID_CONFIG_REASON_METRIC_MATCHER_MORE_THAN_ONE_ATOM, /*metric id=*/3,
398 StringToId("BATTERY_LOW")));
399 }
400
TEST_F(MetricsManagerUtilTest,TestCircleLogMatcherDependency)401 TEST_F(MetricsManagerUtilTest, TestCircleLogMatcherDependency) {
402 optional<InvalidConfigReason> expectedInvalidConfigReason =
403 createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CYCLE,
404 StringToId("SCREEN_ON_OR_OFF"));
405 expectedInvalidConfigReason->matcherIds.push_back(StringToId("SCREEN_ON_OR_OFF"));
406
407 EXPECT_EQ(initConfig(buildCircleMatchers()), expectedInvalidConfigReason);
408 }
409
TEST_F(MetricsManagerUtilTest,TestMissingMatchers)410 TEST_F(MetricsManagerUtilTest, TestMissingMatchers) {
411 optional<InvalidConfigReason> expectedInvalidConfigReason =
412 createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_CHILD_NOT_FOUND,
413 StringToId("SCREEN_ON_OR_OFF"));
414 expectedInvalidConfigReason->matcherIds.push_back(StringToId("ABC"));
415
416 EXPECT_EQ(initConfig(buildMissingMatchers()), expectedInvalidConfigReason);
417 }
418
TEST_F(MetricsManagerUtilTest,TestMissingPredicate)419 TEST_F(MetricsManagerUtilTest, TestMissingPredicate) {
420 EXPECT_EQ(
421 initConfig(buildMissingPredicate()),
422 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_METRIC_CONDITION_NOT_FOUND,
423 /*metric id=*/3, StringToId("SOME_CONDITION")));
424 }
425
TEST_F(MetricsManagerUtilTest,TestCirclePredicateDependency)426 TEST_F(MetricsManagerUtilTest, TestCirclePredicateDependency) {
427 optional<InvalidConfigReason> expectedInvalidConfigReason =
428 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CYCLE,
429 StringToId("SCREEN_IS_EITHER_ON_OFF"));
430 expectedInvalidConfigReason->conditionIds.push_back(StringToId("SCREEN_IS_EITHER_ON_OFF"));
431
432 EXPECT_EQ(initConfig(buildCirclePredicates()), expectedInvalidConfigReason);
433 }
434
TEST_F(MetricsManagerUtilTest,TestAlertWithUnknownMetric)435 TEST_F(MetricsManagerUtilTest, TestAlertWithUnknownMetric) {
436 EXPECT_EQ(initConfig(buildAlertWithUnknownMetric()),
437 createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
438 /*metric id=*/2, /*matcher id=*/3));
439 }
440
TEST_F(MetricsManagerUtilTest,TestMetricWithMultipleActivations)441 TEST_F(MetricsManagerUtilTest, TestMetricWithMultipleActivations) {
442 StatsdConfig config;
443 int64_t metricId = 1;
444 auto metric_activation1 = config.add_metric_activation();
445 metric_activation1->set_metric_id(metricId);
446 metric_activation1->set_activation_type(ACTIVATE_IMMEDIATELY);
447 auto metric_activation2 = config.add_metric_activation();
448 metric_activation2->set_metric_id(metricId);
449 metric_activation2->set_activation_type(ACTIVATE_IMMEDIATELY);
450
451 EXPECT_EQ(initConfig(config),
452 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS, metricId));
453 }
454
TEST_F(MetricsManagerUtilTest,TestCountMetricMissingIdOrWhat)455 TEST_F(MetricsManagerUtilTest, TestCountMetricMissingIdOrWhat) {
456 StatsdConfig config;
457 int64_t metricId = 1;
458 CountMetric* metric = config.add_count_metric();
459 metric->set_id(metricId);
460
461 EXPECT_EQ(initConfig(config),
462 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
463 }
464
TEST_F(MetricsManagerUtilTest,TestCountMetricConditionlinkNoCondition)465 TEST_F(MetricsManagerUtilTest, TestCountMetricConditionlinkNoCondition) {
466 StatsdConfig config;
467 CountMetric* metric = config.add_count_metric();
468 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
469 /*condition=*/nullopt, /*states=*/{});
470 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
471
472 auto link = metric->add_links();
473 link->set_condition(1);
474
475 EXPECT_EQ(initConfig(config),
476 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
477 StringToId("Count")));
478 }
479
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingIdOrWhat)480 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingIdOrWhat) {
481 StatsdConfig config;
482 int64_t metricId = 1;
483 DurationMetric* metric = config.add_duration_metric();
484 metric->set_id(metricId);
485
486 EXPECT_EQ(initConfig(config),
487 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
488 }
489
TEST_F(MetricsManagerUtilTest,TestDurationMetricConditionlinkNoCondition)490 TEST_F(MetricsManagerUtilTest, TestDurationMetricConditionlinkNoCondition) {
491 StatsdConfig config;
492 DurationMetric* metric = config.add_duration_metric();
493 *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
494 /*condition=*/nullopt, /*states=*/{});
495 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
496 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
497 *config.add_predicate() = CreateScreenIsOnPredicate();
498
499 auto link = metric->add_links();
500 link->set_condition(1);
501
502 EXPECT_EQ(initConfig(config),
503 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
504 StringToId("Duration")));
505 }
506
TEST_F(MetricsManagerUtilTest,TestGaugeMetricMissingIdOrWhat)507 TEST_F(MetricsManagerUtilTest, TestGaugeMetricMissingIdOrWhat) {
508 StatsdConfig config;
509 int64_t metricId = 1;
510 GaugeMetric* metric = config.add_gauge_metric();
511 metric->set_id(metricId);
512
513 EXPECT_EQ(initConfig(config),
514 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
515 }
516
TEST_F(MetricsManagerUtilTest,TestGaugeMetricConditionlinkNoCondition)517 TEST_F(MetricsManagerUtilTest, TestGaugeMetricConditionlinkNoCondition) {
518 StatsdConfig config;
519 GaugeMetric* metric = config.add_gauge_metric();
520 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
521 /*samplingType=*/GaugeMetric_SamplingType_FIRST_N_SAMPLES,
522 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
523 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
524
525 auto link = metric->add_links();
526 link->set_condition(1);
527
528 EXPECT_EQ(initConfig(config),
529 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
530 StringToId("Gauge")));
531 }
532
TEST_F(MetricsManagerUtilTest,TestEventMetricMissingIdOrWhat)533 TEST_F(MetricsManagerUtilTest, TestEventMetricMissingIdOrWhat) {
534 StatsdConfig config;
535 int64_t metricId = 1;
536 EventMetric* metric = config.add_event_metric();
537 metric->set_id(metricId);
538
539 EXPECT_EQ(initConfig(config),
540 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
541 }
542
TEST_F(MetricsManagerUtilTest,TestEventMetricConditionlinkNoCondition)543 TEST_F(MetricsManagerUtilTest, TestEventMetricConditionlinkNoCondition) {
544 StatsdConfig config;
545 EventMetric* metric = config.add_event_metric();
546 *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
547 /*condition=*/nullopt);
548 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
549
550 auto link = metric->add_links();
551 link->set_condition(1);
552
553 EXPECT_EQ(initConfig(config),
554 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
555 StringToId("Event")));
556 }
557
TEST_F(MetricsManagerUtilTest,TestEventMetricInvalidSamplingPercentage)558 TEST_F(MetricsManagerUtilTest, TestEventMetricInvalidSamplingPercentage) {
559 StatsdConfig config;
560 EventMetric* metric = config.add_event_metric();
561 *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
562 /*condition=*/nullopt);
563 metric->set_sampling_percentage(101);
564 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
565
566 EXPECT_EQ(initConfig(config),
567 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
568 StringToId("Event")));
569 }
570
TEST_F(MetricsManagerUtilTest,TestEventMetricInvalidSamplingPercentageZero)571 TEST_F(MetricsManagerUtilTest, TestEventMetricInvalidSamplingPercentageZero) {
572 StatsdConfig config;
573 EventMetric* metric = config.add_event_metric();
574 *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
575 /*condition=*/nullopt);
576 metric->set_sampling_percentage(0);
577 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
578
579 EXPECT_EQ(initConfig(config),
580 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
581 StringToId("Event")));
582 }
583
TEST_F(MetricsManagerUtilTest,TestEventMetricValidSamplingPercentage)584 TEST_F(MetricsManagerUtilTest, TestEventMetricValidSamplingPercentage) {
585 StatsdConfig config;
586 EventMetric* metric = config.add_event_metric();
587 *metric = createEventMetric(/*name=*/"Event", /*what=*/StringToId("ScreenTurnedOn"),
588 /*condition=*/nullopt);
589 metric->set_sampling_percentage(50);
590 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
591
592 EXPECT_EQ(initConfig(config), nullopt);
593 }
594
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidSamplingPercentage)595 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidSamplingPercentage) {
596 StatsdConfig config;
597 GaugeMetric* metric = config.add_gauge_metric();
598 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
599 GaugeMetric::FIRST_N_SAMPLES,
600 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
601 metric->set_sampling_percentage(101);
602 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
603
604 EXPECT_EQ(initConfig(config),
605 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
606 StringToId("Gauge")));
607 }
608
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidSamplingPercentageZero)609 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidSamplingPercentageZero) {
610 StatsdConfig config;
611 GaugeMetric* metric = config.add_gauge_metric();
612 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
613 GaugeMetric::FIRST_N_SAMPLES,
614 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
615 metric->set_sampling_percentage(0);
616 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
617
618 EXPECT_EQ(initConfig(config),
619 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_SAMPLING_PERCENTAGE,
620 StringToId("Gauge")));
621 }
622
TEST_F(MetricsManagerUtilTest,TestGaugeMetricValidSamplingPercentage)623 TEST_F(MetricsManagerUtilTest, TestGaugeMetricValidSamplingPercentage) {
624 StatsdConfig config;
625 GaugeMetric* metric = config.add_gauge_metric();
626 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
627 GaugeMetric::FIRST_N_SAMPLES,
628 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
629 metric->set_sampling_percentage(50);
630 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
631
632 EXPECT_EQ(initConfig(config), nullopt);
633 }
634
TEST_F(MetricsManagerUtilTest,TestPulledGaugeMetricWithSamplingPercentage)635 TEST_F(MetricsManagerUtilTest, TestPulledGaugeMetricWithSamplingPercentage) {
636 StatsdConfig config;
637 GaugeMetric* metric = config.add_gauge_metric();
638 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
639 GaugeMetric::FIRST_N_SAMPLES,
640 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
641 metric->set_sampling_percentage(50);
642 *config.add_atom_matcher() =
643 CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
644
645 EXPECT_EQ(initConfig(config),
646 InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_PULLED_WITH_SAMPLING,
647 StringToId("Gauge")));
648 }
649
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidPullProbability)650 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidPullProbability) {
651 StatsdConfig config;
652 GaugeMetric* metric = config.add_gauge_metric();
653 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
654 GaugeMetric::FIRST_N_SAMPLES,
655 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
656 metric->set_pull_probability(101);
657 *config.add_atom_matcher() =
658 CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
659
660 EXPECT_EQ(initConfig(config),
661 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_PULL_PROBABILITY,
662 StringToId("Gauge")));
663 }
664
TEST_F(MetricsManagerUtilTest,TestGaugeMetricInvalidPullProbabilityZero)665 TEST_F(MetricsManagerUtilTest, TestGaugeMetricInvalidPullProbabilityZero) {
666 StatsdConfig config;
667 GaugeMetric* metric = config.add_gauge_metric();
668 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
669 GaugeMetric::FIRST_N_SAMPLES,
670 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
671 metric->set_pull_probability(0);
672 *config.add_atom_matcher() =
673 CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
674
675 EXPECT_EQ(initConfig(config),
676 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_INCORRECT_PULL_PROBABILITY,
677 StringToId("Gauge")));
678 }
679
TEST_F(MetricsManagerUtilTest,TestGaugeMetricValidPullProbability)680 TEST_F(MetricsManagerUtilTest, TestGaugeMetricValidPullProbability) {
681 StatsdConfig config;
682 GaugeMetric* metric = config.add_gauge_metric();
683 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
684 GaugeMetric::FIRST_N_SAMPLES,
685 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
686 metric->set_pull_probability(50);
687 *config.add_atom_matcher() =
688 CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
689
690 EXPECT_EQ(initConfig(config), nullopt);
691 }
692
TEST_F(MetricsManagerUtilTest,TestPushedGaugeMetricWithPullProbability)693 TEST_F(MetricsManagerUtilTest, TestPushedGaugeMetricWithPullProbability) {
694 StatsdConfig config;
695 GaugeMetric* metric = config.add_gauge_metric();
696 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("ScreenTurnedOn"),
697 GaugeMetric::FIRST_N_SAMPLES,
698 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
699 metric->set_pull_probability(50);
700 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
701
702 EXPECT_EQ(initConfig(config),
703 InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_PUSHED_WITH_PULL_PROBABILITY,
704 StringToId("Gauge")));
705 }
706
TEST_F(MetricsManagerUtilTest,TestGaugeMetricRandomOneSampleWithPullProbability)707 TEST_F(MetricsManagerUtilTest, TestGaugeMetricRandomOneSampleWithPullProbability) {
708 StatsdConfig config;
709 GaugeMetric* metric = config.add_gauge_metric();
710 *metric = createGaugeMetric(/*name=*/"Gauge", /*what=*/StringToId("SubsystemSleep"),
711 GaugeMetric::RANDOM_ONE_SAMPLE,
712 /*condition=*/nullopt, /*triggerEvent=*/nullopt);
713 metric->set_pull_probability(50);
714 *config.add_atom_matcher() =
715 CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
716
717 EXPECT_EQ(initConfig(config),
718 InvalidConfigReason(
719 INVALID_CONFIG_REASON_GAUGE_METRIC_RANDOM_ONE_SAMPLE_WITH_PULL_PROBABILITY,
720 StringToId("Gauge")));
721 }
722
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMissingIdOrWhat)723 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMissingIdOrWhat) {
724 StatsdConfig config;
725 int64_t metricId = 1;
726 ValueMetric* metric = config.add_value_metric();
727 metric->set_id(metricId);
728
729 EXPECT_EQ(initConfig(config),
730 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
731 }
732
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricConditionlinkNoCondition)733 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricConditionlinkNoCondition) {
734 StatsdConfig config;
735 ValueMetric* metric = config.add_value_metric();
736 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
737 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
738 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
739
740 auto link = metric->add_links();
741 link->set_condition(1);
742
743 EXPECT_EQ(initConfig(config),
744 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
745 StringToId("NumericValue")));
746 }
747
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHasBothSingleAndMultipleAggTypes)748 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHasBothSingleAndMultipleAggTypes) {
749 StatsdConfig config;
750 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
751
752 ValueMetric* metric = config.add_value_metric();
753 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
754 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
755 metric->set_aggregation_type(ValueMetric::SUM);
756 metric->add_aggregation_types(ValueMetric::SUM);
757 metric->add_aggregation_types(ValueMetric::MIN);
758
759 EXPECT_EQ(initConfig(config),
760 InvalidConfigReason(
761 INVALID_CONFIG_REASON_VALUE_METRIC_DEFINES_SINGLE_AND_MULTIPLE_AGG_TYPES,
762 StringToId("NumericValue")));
763 }
764
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMoreAggTypesThanValueFields)765 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMoreAggTypesThanValueFields) {
766 StatsdConfig config;
767 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
768
769 ValueMetric* metric = config.add_value_metric();
770 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
771 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
772 metric->add_aggregation_types(ValueMetric::SUM);
773 metric->add_aggregation_types(ValueMetric::MIN);
774
775 EXPECT_EQ(
776 initConfig(config),
777 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_AGG_TYPES_DNE_VALUE_FIELDS_SIZE,
778 StringToId("NumericValue")));
779 }
780
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMoreValueFieldsThanAggTypes)781 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMoreValueFieldsThanAggTypes) {
782 StatsdConfig config;
783 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
784
785 ValueMetric* metric = config.add_value_metric();
786 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
787 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
788 // This only fails if the repeated aggregation field is used. If the single field is used,
789 // we will apply this aggregation type to all value fields.
790 metric->add_aggregation_types(ValueMetric::SUM);
791 metric->add_aggregation_types(ValueMetric::MIN);
792 *metric->mutable_value_field() = CreateDimensions(
793 util::SUBSYSTEM_SLEEP_STATE, {3 /* count */, 4 /* time_millis */, 3 /* count */});
794
795 EXPECT_EQ(
796 initConfig(config),
797 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_AGG_TYPES_DNE_VALUE_FIELDS_SIZE,
798 StringToId("NumericValue")));
799 }
800
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricDefaultAggTypeOutOfOrderFields)801 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricDefaultAggTypeOutOfOrderFields) {
802 StatsdConfig config;
803 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
804
805 ValueMetric* metric = config.add_value_metric();
806 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
807 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
808 *metric->mutable_value_field() =
809 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time_millis */, 3 /* count */});
810
811 EXPECT_EQ(initConfig(config), nullopt);
812 }
813
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMultipleAggTypesOutOfOrderFields)814 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMultipleAggTypesOutOfOrderFields) {
815 StatsdConfig config;
816 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
817
818 ValueMetric* metric = config.add_value_metric();
819 *metric = createValueMetric(/*name=*/"NumericValue", /*what=*/CreateScreenTurnedOnAtomMatcher(),
820 /*valueField=*/2, /*condition=*/nullopt, /*states=*/{});
821 metric->add_aggregation_types(ValueMetric::SUM);
822 metric->add_aggregation_types(ValueMetric::MIN);
823 metric->add_aggregation_types(ValueMetric::SUM);
824 *metric->mutable_value_field() = CreateDimensions(
825 util::SUBSYSTEM_SLEEP_STATE, {3 /* count */, 4 /* time_millis */, 3 /* count */});
826
827 EXPECT_EQ(initConfig(config), nullopt);
828 }
829
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingIdOrWhat)830 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingIdOrWhat) {
831 StatsdConfig config;
832 int64_t metricId = 1;
833 KllMetric* metric = config.add_kll_metric();
834 metric->set_id(metricId);
835
836 EXPECT_EQ(initConfig(config),
837 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metricId));
838 }
839
TEST_F(MetricsManagerUtilTest,TestKllMetricConditionlinkNoCondition)840 TEST_F(MetricsManagerUtilTest, TestKllMetricConditionlinkNoCondition) {
841 StatsdConfig config;
842 KllMetric* metric = config.add_kll_metric();
843 *metric = createKllMetric(/*name=*/"Kll", /*what=*/CreateScreenTurnedOnAtomMatcher(),
844 /*valueField=*/2, /*condition=*/nullopt);
845 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
846
847 auto link = metric->add_links();
848 link->set_condition(1);
849
850 EXPECT_EQ(initConfig(config),
851 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION,
852 StringToId("Kll")));
853 }
854
TEST_F(MetricsManagerUtilTest,TestMetricMatcherNotFound)855 TEST_F(MetricsManagerUtilTest, TestMetricMatcherNotFound) {
856 StatsdConfig config;
857 *config.add_count_metric() =
858 createCountMetric(/*name=*/"Count", /*what=*/StringToId("SOME MATCHER"),
859 /*condition=*/nullopt, /*states=*/{});
860
861 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
862 INVALID_CONFIG_REASON_METRIC_MATCHER_NOT_FOUND,
863 StringToId("Count"), StringToId("SOME MATCHER")));
864 }
865
TEST_F(MetricsManagerUtilTest,TestMetricConditionLinkNotFound)866 TEST_F(MetricsManagerUtilTest, TestMetricConditionLinkNotFound) {
867 StatsdConfig config;
868 CountMetric* metric = config.add_count_metric();
869 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
870 /*condition=*/StringToId("ScreenIsOn"), /*states=*/{});
871 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
872 *config.add_predicate() = CreateScreenIsOnPredicate();
873
874 auto link = metric->add_links();
875 link->set_condition(StringToId("SOME CONDITION"));
876
877 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
878 INVALID_CONFIG_REASON_METRIC_CONDITION_LINK_NOT_FOUND,
879 StringToId("Count"), StringToId("SOME CONDITION")));
880 }
881
TEST_F(MetricsManagerUtilTest,TestMetricStateNotFound)882 TEST_F(MetricsManagerUtilTest, TestMetricStateNotFound) {
883 StatsdConfig config;
884 *config.add_count_metric() =
885 createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
886 /*condition=*/nullopt, /*states=*/{StringToId("SOME STATE")});
887 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
888
889 EXPECT_EQ(initConfig(config),
890 createInvalidConfigReasonWithState(INVALID_CONFIG_REASON_METRIC_STATE_NOT_FOUND,
891 StringToId("Count"), StringToId("SOME STATE")));
892 }
893
TEST_F(MetricsManagerUtilTest,TestMetricStatelinkNoState)894 TEST_F(MetricsManagerUtilTest, TestMetricStatelinkNoState) {
895 StatsdConfig config;
896 CountMetric* metric = config.add_count_metric();
897 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
898 /*condition=*/nullopt, /*states=*/{});
899 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
900
901 auto link = metric->add_state_link();
902 link->set_state_atom_id(2);
903
904 EXPECT_EQ(initConfig(config),
905 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE,
906 StringToId("Count")));
907 }
908
TEST_F(MetricsManagerUtilTest,TestMetricBadThreshold)909 TEST_F(MetricsManagerUtilTest, TestMetricBadThreshold) {
910 StatsdConfig config;
911 CountMetric* metric = config.add_count_metric();
912 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
913 /*condition=*/nullopt, /*states=*/{});
914 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
915
916 metric->mutable_threshold()->set_lt_float(1.0);
917
918 EXPECT_EQ(initConfig(config),
919 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_BAD_THRESHOLD, StringToId("Count")));
920 }
921
TEST_F(MetricsManagerUtilTest,TestMetricActivationMatcherNotFound)922 TEST_F(MetricsManagerUtilTest, TestMetricActivationMatcherNotFound) {
923 StatsdConfig config;
924 *config.add_count_metric() =
925 createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
926 /*condition=*/nullopt, /*states=*/{});
927 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
928 auto metric_activation = config.add_metric_activation();
929 metric_activation->set_metric_id(StringToId("Count"));
930 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
931 auto event_activation = metric_activation->add_event_activation();
932
933 event_activation->set_atom_matcher_id(StringToId("SOME_MATCHER"));
934
935 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
936 INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND,
937 StringToId("Count"), StringToId("SOME_MATCHER")));
938 }
939
TEST_F(MetricsManagerUtilTest,TestMetricDeactivationMatcherNotFound)940 TEST_F(MetricsManagerUtilTest, TestMetricDeactivationMatcherNotFound) {
941 StatsdConfig config;
942 *config.add_count_metric() =
943 createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
944 /*condition=*/nullopt, /*states=*/{});
945 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
946 auto metric_activation = config.add_metric_activation();
947 metric_activation->set_metric_id(StringToId("Count"));
948 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
949 auto event_activation = metric_activation->add_event_activation();
950 event_activation->set_atom_matcher_id(StringToId("ScreenTurnedOn"));
951
952 event_activation->set_deactivation_atom_matcher_id(StringToId("SOME_MATCHER"));
953
954 EXPECT_EQ(initConfig(config),
955 createInvalidConfigReasonWithMatcher(
956 INVALID_CONFIG_REASON_METRIC_DEACTIVATION_MATCHER_NOT_FOUND,
957 StringToId("Count"), StringToId("SOME_MATCHER")));
958 }
959
TEST_F(MetricsManagerUtilTest,TestMetricSlicedStateAtomAllowedFromAnyUid)960 TEST_F(MetricsManagerUtilTest, TestMetricSlicedStateAtomAllowedFromAnyUid) {
961 StatsdConfig config;
962 CountMetric* metric = config.add_count_metric();
963 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
964 /*condition=*/nullopt, /*states=*/{});
965 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
966
967 *config.add_state() = CreateScreenState();
968 metric->add_slice_by_state(StringToId("ScreenState"));
969 config.add_whitelisted_atom_ids(util::SCREEN_STATE_CHANGED);
970
971 EXPECT_EQ(
972 initConfig(config),
973 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
974 StringToId("Count")));
975 }
976
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotSimple)977 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotSimple) {
978 StatsdConfig config;
979 *config.add_duration_metric() =
980 createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsEitherOnOff"),
981 /*condition=*/nullopt, /*states=*/{});
982 *config.add_predicate() = CreateScreenIsOnPredicate();
983 *config.add_predicate() = CreateScreenIsOffPredicate();
984
985 auto condition = config.add_predicate();
986 condition->set_id(StringToId("ScreenIsEitherOnOff"));
987 Predicate_Combination* combination = condition->mutable_combination();
988 combination->set_operation(LogicalOperation::OR);
989 combination->add_predicate(StringToId("ScreenIsOn"));
990 combination->add_predicate(StringToId("ScreenIsOff"));
991
992 EXPECT_EQ(initConfig(config),
993 createInvalidConfigReasonWithPredicate(
994 INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_SIMPLE, StringToId("Duration"),
995 StringToId("ScreenIsEitherOnOff")));
996 }
997
TEST_F(MetricsManagerUtilTest,TestDurationMetricWhatNotFound)998 TEST_F(MetricsManagerUtilTest, TestDurationMetricWhatNotFound) {
999 StatsdConfig config;
1000 int64_t metricId = 1;
1001 DurationMetric* metric = config.add_duration_metric();
1002 metric->set_id(metricId);
1003
1004 metric->set_what(StringToId("SOME WHAT"));
1005
1006 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
1007 INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_FOUND,
1008 metricId, StringToId("SOME WHAT")));
1009 }
1010
TEST_F(MetricsManagerUtilTest,TestDurationMetricMissingStart)1011 TEST_F(MetricsManagerUtilTest, TestDurationMetricMissingStart) {
1012 StatsdConfig config;
1013 *config.add_duration_metric() =
1014 createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("SCREEN_IS_ON"),
1015 /*condition=*/nullopt, /*states=*/{});
1016 auto condition = config.add_predicate();
1017 condition->set_id(StringToId("SCREEN_IS_ON"));
1018
1019 SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
1020 simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
1021
1022 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithPredicate(
1023 INVALID_CONFIG_REASON_DURATION_METRIC_MISSING_START,
1024 StringToId("Duration"), StringToId("SCREEN_IS_ON")));
1025 }
1026
TEST_F(MetricsManagerUtilTest,TestDurationMetricMaxSparseHasSpliceByState)1027 TEST_F(MetricsManagerUtilTest, TestDurationMetricMaxSparseHasSpliceByState) {
1028 StatsdConfig config;
1029 DurationMetric* metric = config.add_duration_metric();
1030 *metric = createDurationMetric(/*name=*/"Duration", /*what=*/StringToId("ScreenIsOn"),
1031 /*condition=*/nullopt, /*states=*/{});
1032 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1033 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
1034 *config.add_predicate() = CreateScreenIsOnPredicate();
1035 *config.add_state() = CreateScreenState();
1036
1037 metric->add_slice_by_state(StringToId("ScreenState"));
1038 metric->set_aggregation_type(DurationMetric::MAX_SPARSE);
1039
1040 EXPECT_EQ(
1041 initConfig(config),
1042 InvalidConfigReason(INVALID_CONFIG_REASON_DURATION_METRIC_MAX_SPARSE_HAS_SLICE_BY_STATE,
1043 StringToId("Duration")));
1044 }
1045
TEST_F(MetricsManagerUtilTest,TestValueMetricMissingValueField)1046 TEST_F(MetricsManagerUtilTest, TestValueMetricMissingValueField) {
1047 StatsdConfig config;
1048 int64_t metricId = 1;
1049 ValueMetric* metric = config.add_value_metric();
1050 metric->set_id(metricId);
1051 metric->set_what(1);
1052
1053 EXPECT_EQ(
1054 initConfig(config),
1055 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_MISSING_VALUE_FIELD, metricId));
1056 }
1057
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasPositionAll)1058 TEST_F(MetricsManagerUtilTest, TestValueMetricValueFieldHasPositionAll) {
1059 StatsdConfig config;
1060 int64_t metricId = 1;
1061 ValueMetric* metric = config.add_value_metric();
1062 metric->set_id(metricId);
1063 metric->set_what(1);
1064
1065 metric->mutable_value_field()->add_child()->set_field(2);
1066 metric->mutable_value_field()->mutable_child(0)->set_position(ALL);
1067
1068 EXPECT_EQ(initConfig(config),
1069 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL,
1070 metricId));
1071 }
1072
TEST_F(MetricsManagerUtilTest,TestValueMetricHasIncorrectValueField)1073 TEST_F(MetricsManagerUtilTest, TestValueMetricHasIncorrectValueField) {
1074 StatsdConfig config;
1075 int64_t metricId = 1;
1076 ValueMetric* metric = config.add_value_metric();
1077 metric->set_id(metricId);
1078 metric->set_what(1);
1079
1080 metric->mutable_value_field()->set_position(ANY);
1081
1082 EXPECT_EQ(initConfig(config),
1083 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HAS_INCORRECT_VALUE_FIELD,
1084 metricId));
1085 }
1086
TEST_F(MetricsManagerUtilTest,TestKllMetricMissingKllField)1087 TEST_F(MetricsManagerUtilTest, TestKllMetricMissingKllField) {
1088 StatsdConfig config;
1089 int64_t metricId = 1;
1090 KllMetric* metric = config.add_kll_metric();
1091 metric->set_id(metricId);
1092 metric->set_what(1);
1093
1094 EXPECT_EQ(initConfig(config),
1095 InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_MISSING_KLL_FIELD, metricId));
1096 }
1097
TEST_F(MetricsManagerUtilTest,TestKllMetricKllFieldHasPositionAll)1098 TEST_F(MetricsManagerUtilTest, TestKllMetricKllFieldHasPositionAll) {
1099 StatsdConfig config;
1100 int64_t metricId = 1;
1101 KllMetric* metric = config.add_kll_metric();
1102 metric->set_id(metricId);
1103 metric->set_what(1);
1104
1105 metric->mutable_kll_field()->set_position(ALL);
1106
1107 EXPECT_EQ(initConfig(config),
1108 InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_KLL_FIELD_HAS_POSITION_ALL,
1109 metricId));
1110 }
1111
TEST_F(MetricsManagerUtilTest,TestKllMetricHasIncorrectKllField)1112 TEST_F(MetricsManagerUtilTest, TestKllMetricHasIncorrectKllField) {
1113 StatsdConfig config;
1114 int64_t metricId = 1;
1115 KllMetric* metric = config.add_kll_metric();
1116 metric->set_id(metricId);
1117 metric->set_what(1);
1118
1119 metric->mutable_kll_field()->set_position(ANY);
1120
1121 EXPECT_EQ(initConfig(config),
1122 InvalidConfigReason(INVALID_CONFIG_REASON_KLL_METRIC_HAS_INCORRECT_KLL_FIELD,
1123 metricId));
1124 }
1125
TEST_F(MetricsManagerUtilTest,TestGaugeMetricIncorrectFieldFilter)1126 TEST_F(MetricsManagerUtilTest, TestGaugeMetricIncorrectFieldFilter) {
1127 StatsdConfig config;
1128 int64_t metricId = 1;
1129 GaugeMetric* metric = config.add_gauge_metric();
1130 metric->set_id(metricId);
1131 metric->set_what(1);
1132
1133 EXPECT_EQ(initConfig(config),
1134 InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_INCORRECT_FIELD_FILTER,
1135 metricId));
1136 }
1137
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoPullAtom)1138 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoPullAtom) {
1139 StatsdConfig config;
1140 int64_t metricId = 1;
1141 GaugeMetric* metric = config.add_gauge_metric();
1142 metric->set_id(metricId);
1143 metric->set_what(StringToId("ScreenTurnedOn"));
1144 metric->mutable_gauge_fields_filter()->set_include_all(true);
1145 metric->set_trigger_event(1);
1146
1147 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1148
1149 EXPECT_EQ(
1150 initConfig(config),
1151 InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_PULL_ATOM, metricId));
1152 }
1153
TEST_F(MetricsManagerUtilTest,TestGaugeMetricTriggerNoFirstNSamples)1154 TEST_F(MetricsManagerUtilTest, TestGaugeMetricTriggerNoFirstNSamples) {
1155 StatsdConfig config;
1156 int64_t metricId = 1;
1157 GaugeMetric* metric = config.add_gauge_metric();
1158 metric->set_id(metricId);
1159 metric->set_what(StringToId("Matcher"));
1160 *config.add_atom_matcher() =
1161 CreateSimpleAtomMatcher(/*name=*/"Matcher", /*atomId=*/util::SUBSYSTEM_SLEEP_STATE);
1162
1163 metric->mutable_gauge_fields_filter()->set_include_all(true);
1164 metric->set_trigger_event(StringToId("Matcher"));
1165
1166 EXPECT_EQ(initConfig(config),
1167 InvalidConfigReason(INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_FIRST_N_SAMPLES,
1168 metricId));
1169 }
1170
TEST_F(MetricsManagerUtilTest,TestMatcherDuplicate)1171 TEST_F(MetricsManagerUtilTest, TestMatcherDuplicate) {
1172 StatsdConfig config;
1173
1174 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1175 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1176
1177 EXPECT_EQ(initConfig(config),
1178 createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
1179 StringToId("ScreenTurnedOn")));
1180 }
1181
TEST_F(MetricsManagerUtilTest,TestMatcherNoOperation)1182 TEST_F(MetricsManagerUtilTest, TestMatcherNoOperation) {
1183 StatsdConfig config;
1184 int64_t matcherId = 1;
1185
1186 AtomMatcher* matcher = config.add_atom_matcher();
1187 matcher->set_id(matcherId);
1188 matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1189
1190 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithMatcher(
1191 INVALID_CONFIG_REASON_MATCHER_NO_OPERATION, matcherId));
1192 }
1193
TEST_F(MetricsManagerUtilTest,TestMatcherNotOperationIsNotUnary)1194 TEST_F(MetricsManagerUtilTest, TestMatcherNotOperationIsNotUnary) {
1195 StatsdConfig config;
1196 int64_t matcherId = 1;
1197 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
1198 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
1199
1200 AtomMatcher* matcher = config.add_atom_matcher();
1201 matcher->set_id(matcherId);
1202 matcher->mutable_combination()->set_operation(LogicalOperation::NOT);
1203 matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOn"));
1204 matcher->mutable_combination()->add_matcher(StringToId("ScreenTurnedOff"));
1205
1206 EXPECT_EQ(initConfig(config),
1207 createInvalidConfigReasonWithMatcher(
1208 INVALID_CONFIG_REASON_MATCHER_NOT_OPERATION_IS_NOT_UNARY, matcherId));
1209 }
1210
TEST_F(MetricsManagerUtilTest,TestConditionChildNotFound)1211 TEST_F(MetricsManagerUtilTest, TestConditionChildNotFound) {
1212 StatsdConfig config;
1213 int64_t conditionId = 1;
1214 int64_t childConditionId = 2;
1215
1216 Predicate* condition = config.add_predicate();
1217 condition->set_id(conditionId);
1218 condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1219 condition->mutable_combination()->add_predicate(childConditionId);
1220
1221 optional<InvalidConfigReason> expectedInvalidConfigReason =
1222 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_CHILD_NOT_FOUND,
1223 conditionId);
1224 expectedInvalidConfigReason->conditionIds.push_back(childConditionId);
1225 EXPECT_EQ(initConfig(config), expectedInvalidConfigReason);
1226 }
1227
TEST_F(MetricsManagerUtilTest,TestConditionDuplicate)1228 TEST_F(MetricsManagerUtilTest, TestConditionDuplicate) {
1229 StatsdConfig config;
1230 *config.add_predicate() = CreateScreenIsOnPredicate();
1231 *config.add_predicate() = CreateScreenIsOnPredicate();
1232
1233 EXPECT_EQ(initConfig(config),
1234 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
1235 StringToId("ScreenIsOn")));
1236 }
1237
TEST_F(MetricsManagerUtilTest,TestConditionNoOperation)1238 TEST_F(MetricsManagerUtilTest, TestConditionNoOperation) {
1239 StatsdConfig config;
1240 int64_t conditionId = 1;
1241 *config.add_predicate() = CreateScreenIsOnPredicate();
1242
1243 Predicate* condition = config.add_predicate();
1244 condition->set_id(conditionId);
1245 condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1246
1247 EXPECT_EQ(initConfig(config),
1248 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_NO_OPERATION,
1249 conditionId));
1250 }
1251
TEST_F(MetricsManagerUtilTest,TestConditionNotOperationIsNotUnary)1252 TEST_F(MetricsManagerUtilTest, TestConditionNotOperationIsNotUnary) {
1253 StatsdConfig config;
1254 int64_t conditionId = 1;
1255 *config.add_predicate() = CreateScreenIsOnPredicate();
1256 *config.add_predicate() = CreateScreenIsOffPredicate();
1257
1258 Predicate* condition = config.add_predicate();
1259 condition->set_id(conditionId);
1260 condition->mutable_combination()->set_operation(LogicalOperation::NOT);
1261 condition->mutable_combination()->add_predicate(StringToId("ScreenIsOn"));
1262 condition->mutable_combination()->add_predicate(StringToId("ScreenIsOff"));
1263
1264 EXPECT_EQ(initConfig(config),
1265 createInvalidConfigReasonWithPredicate(
1266 INVALID_CONFIG_REASON_CONDITION_NOT_OPERATION_IS_NOT_UNARY, conditionId));
1267 }
1268
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlert)1269 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlert) {
1270 StatsdConfig config;
1271 int64_t alertId = 1;
1272 *config.add_subscription() = createSubscription("Subscription", Subscription::ALERT, alertId);
1273
1274 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlert(
1275 INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1276 StringToId("Subscription"), alertId));
1277 }
1278
TEST_F(MetricsManagerUtilTest,TestSubscriptionRuleNotFoundAlarm)1279 TEST_F(MetricsManagerUtilTest, TestSubscriptionRuleNotFoundAlarm) {
1280 StatsdConfig config;
1281 int64_t alarmId = 1;
1282 *config.add_subscription() = createSubscription("Subscription", Subscription::ALARM, alarmId);
1283
1284 EXPECT_EQ(initConfig(config), createInvalidConfigReasonWithSubscriptionAndAlarm(
1285 INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND,
1286 StringToId("Subscription"), alarmId));
1287 }
1288
TEST_F(MetricsManagerUtilTest,TestSubscriptionSubscriberInfoMissing)1289 TEST_F(MetricsManagerUtilTest, TestSubscriptionSubscriberInfoMissing) {
1290 StatsdConfig config;
1291 Subscription subscription =
1292 createSubscription("Subscription", Subscription::ALERT, /*alert id=*/1);
1293 subscription.clear_subscriber_information();
1294 *config.add_subscription() = subscription;
1295
1296 EXPECT_EQ(initConfig(config),
1297 createInvalidConfigReasonWithSubscription(
1298 INVALID_CONFIG_REASON_SUBSCRIPTION_SUBSCRIBER_INFO_MISSING,
1299 StringToId("Subscription")));
1300 }
1301
TEST_F(MetricsManagerUtilTest,TestAlarmPeriodLessThanOrEqualZero)1302 TEST_F(MetricsManagerUtilTest, TestAlarmPeriodLessThanOrEqualZero) {
1303 StatsdConfig config;
1304 *config.add_alarm() = createAlarm("Alarm", /*offset=*/1, /*period=*/-1);
1305
1306 EXPECT_EQ(initConfig(config),
1307 createInvalidConfigReasonWithAlarm(
1308 INVALID_CONFIG_REASON_ALARM_PERIOD_LESS_THAN_OR_EQUAL_ZERO,
1309 StringToId("Alarm")));
1310 }
1311
TEST_F(MetricsManagerUtilTest,TestAlarmOffsetLessThanOrEqualZero)1312 TEST_F(MetricsManagerUtilTest, TestAlarmOffsetLessThanOrEqualZero) {
1313 StatsdConfig config;
1314 *config.add_alarm() = createAlarm("Alarm", /*offset=*/-1, /*period=*/1);
1315
1316 EXPECT_EQ(initConfig(config),
1317 createInvalidConfigReasonWithAlarm(
1318 INVALID_CONFIG_REASON_ALARM_OFFSET_LESS_THAN_OR_EQUAL_ZERO,
1319 StringToId("Alarm")));
1320 }
1321
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerInvalidMatcher)1322 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerInvalidMatcher) {
1323 sp<UidMap> uidMap = new UidMap();
1324 AtomMatcher matcher;
1325 // Matcher has no contents_case (simple/combination), so it is invalid.
1326 matcher.set_id(21);
1327 optional<InvalidConfigReason> invalidConfigReason;
1328 EXPECT_EQ(createAtomMatchingTracker(matcher, uidMap, invalidConfigReason), nullptr);
1329 EXPECT_EQ(invalidConfigReason,
1330 createInvalidConfigReasonWithMatcher(
1331 INVALID_CONFIG_REASON_MATCHER_MALFORMED_CONTENTS_CASE, matcher.id()));
1332 }
1333
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerSimple)1334 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerSimple) {
1335 int64_t id = 123;
1336 sp<UidMap> uidMap = new UidMap();
1337 AtomMatcher matcher;
1338 matcher.set_id(id);
1339 SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
1340 simpleAtomMatcher->set_atom_id(SCREEN_STATE_ATOM_ID);
1341 simpleAtomMatcher->add_field_value_matcher()->set_field(
1342 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
1343 simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
1344 android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1345
1346 optional<InvalidConfigReason> invalidConfigReason;
1347 sp<AtomMatchingTracker> tracker =
1348 createAtomMatchingTracker(matcher, uidMap, invalidConfigReason);
1349 EXPECT_NE(tracker, nullptr);
1350 EXPECT_EQ(invalidConfigReason, nullopt);
1351
1352 EXPECT_TRUE(tracker->mInitialized);
1353 EXPECT_EQ(tracker->getId(), id);
1354 const set<int>& atomIds = tracker->getAtomIds();
1355 ASSERT_EQ(atomIds.size(), 1);
1356 EXPECT_EQ(atomIds.count(SCREEN_STATE_ATOM_ID), 1);
1357 }
1358
TEST_F(MetricsManagerUtilTest,TestCreateAtomMatchingTrackerCombination)1359 TEST_F(MetricsManagerUtilTest, TestCreateAtomMatchingTrackerCombination) {
1360 int64_t id = 123;
1361 sp<UidMap> uidMap = new UidMap();
1362 AtomMatcher matcher;
1363 matcher.set_id(id);
1364 AtomMatcher_Combination* combination = matcher.mutable_combination();
1365 combination->set_operation(LogicalOperation::OR);
1366 combination->add_matcher(123);
1367 combination->add_matcher(223);
1368
1369 optional<InvalidConfigReason> invalidConfigReason;
1370 sp<AtomMatchingTracker> tracker =
1371 createAtomMatchingTracker(matcher, uidMap, invalidConfigReason);
1372 EXPECT_NE(tracker, nullptr);
1373 EXPECT_EQ(invalidConfigReason, nullopt);
1374
1375 // Combination matchers need to be initialized first.
1376 EXPECT_FALSE(tracker->mInitialized);
1377 EXPECT_EQ(tracker->getId(), id);
1378 const set<int>& atomIds = tracker->getAtomIds();
1379 ASSERT_EQ(atomIds.size(), 0);
1380 }
1381
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerInvalid)1382 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerInvalid) {
1383 const ConfigKey key(123, 456);
1384 // Predicate has no contents_case (simple/combination), so it is invalid.
1385 Predicate predicate;
1386 predicate.set_id(21);
1387 unordered_map<int64_t, int> atomTrackerMap;
1388 optional<InvalidConfigReason> invalidConfigReason;
1389 EXPECT_EQ(createConditionTracker(key, predicate, 0, atomTrackerMap, invalidConfigReason),
1390 nullptr);
1391 EXPECT_EQ(invalidConfigReason,
1392 createInvalidConfigReasonWithPredicate(
1393 INVALID_CONFIG_REASON_CONDITION_MALFORMED_CONTENTS_CASE, predicate.id()));
1394 }
1395
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerSimple)1396 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerSimple) {
1397 int index = 1;
1398 int64_t id = 987;
1399 const ConfigKey key(123, 456);
1400
1401 int startMatcherIndex = 2, stopMatcherIndex = 0, stopAllMatcherIndex = 1;
1402 int64_t startMatcherId = 246, stopMatcherId = 153, stopAllMatcherId = 975;
1403
1404 Predicate predicate;
1405 predicate.set_id(id);
1406 SimplePredicate* simplePredicate = predicate.mutable_simple_predicate();
1407 simplePredicate->set_start(startMatcherId);
1408 simplePredicate->set_stop(stopMatcherId);
1409 simplePredicate->set_stop_all(stopAllMatcherId);
1410
1411 unordered_map<int64_t, int> atomTrackerMap;
1412 atomTrackerMap[startMatcherId] = startMatcherIndex;
1413 atomTrackerMap[stopMatcherId] = stopMatcherIndex;
1414 atomTrackerMap[stopAllMatcherId] = stopAllMatcherIndex;
1415
1416 optional<InvalidConfigReason> invalidConfigReason;
1417 sp<ConditionTracker> tracker =
1418 createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1419 EXPECT_EQ(invalidConfigReason, nullopt);
1420 EXPECT_EQ(tracker->getConditionId(), id);
1421 EXPECT_EQ(tracker->isSliced(), false);
1422 EXPECT_TRUE(tracker->IsSimpleCondition());
1423 const set<int>& interestedMatchers = tracker->getAtomMatchingTrackerIndex();
1424 ASSERT_EQ(interestedMatchers.size(), 3);
1425 ASSERT_EQ(interestedMatchers.count(startMatcherIndex), 1);
1426 ASSERT_EQ(interestedMatchers.count(stopMatcherIndex), 1);
1427 ASSERT_EQ(interestedMatchers.count(stopAllMatcherIndex), 1);
1428 }
1429
TEST_F(MetricsManagerUtilTest,TestCreateConditionTrackerCombination)1430 TEST_F(MetricsManagerUtilTest, TestCreateConditionTrackerCombination) {
1431 int index = 1;
1432 int64_t id = 987;
1433 const ConfigKey key(123, 456);
1434
1435 Predicate predicate;
1436 predicate.set_id(id);
1437 Predicate_Combination* combinationPredicate = predicate.mutable_combination();
1438 combinationPredicate->set_operation(LogicalOperation::AND);
1439 combinationPredicate->add_predicate(888);
1440 combinationPredicate->add_predicate(777);
1441
1442 // Combination conditions must be initialized to set most state.
1443 unordered_map<int64_t, int> atomTrackerMap;
1444 optional<InvalidConfigReason> invalidConfigReason;
1445 sp<ConditionTracker> tracker =
1446 createConditionTracker(key, predicate, index, atomTrackerMap, invalidConfigReason);
1447 EXPECT_EQ(invalidConfigReason, nullopt);
1448 EXPECT_EQ(tracker->getConditionId(), id);
1449 EXPECT_FALSE(tracker->IsSimpleCondition());
1450 }
1451
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerInvalidMetric)1452 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerInvalidMetric) {
1453 Alert alert;
1454 alert.set_id(123);
1455 alert.set_metric_id(1);
1456 alert.set_trigger_if_sum_gt(1);
1457 alert.set_num_buckets(1);
1458
1459 sp<AlarmMonitor> anomalyAlarmMonitor;
1460 vector<sp<MetricProducer>> metricProducers;
1461 optional<InvalidConfigReason> invalidConfigReason;
1462 // Pass in empty metric producers, causing an error.
1463 EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123, {},
1464 metricProducers, invalidConfigReason),
1465 nullopt);
1466 EXPECT_EQ(invalidConfigReason,
1467 createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND,
1468 alert.metric_id(), alert.id()));
1469 }
1470
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerNoThreshold)1471 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerNoThreshold) {
1472 int64_t metricId = 1;
1473 Alert alert;
1474 alert.set_id(123);
1475 alert.set_metric_id(metricId);
1476 alert.set_num_buckets(1);
1477
1478 CountMetric metric;
1479 metric.set_id(metricId);
1480 metric.set_bucket(ONE_MINUTE);
1481 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1482 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1483 vector<sp<MetricProducer>> metricProducers(
1484 {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1485 0x0123456789, 0, 0, provider)});
1486 sp<AlarmMonitor> anomalyAlarmMonitor;
1487 optional<InvalidConfigReason> invalidConfigReason;
1488 EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1489 {{1, 0}}, metricProducers, invalidConfigReason),
1490 nullopt);
1491 EXPECT_EQ(invalidConfigReason,
1492 createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_THRESHOLD_MISSING,
1493 alert.id()));
1494 }
1495
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerMissingBuckets)1496 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerMissingBuckets) {
1497 int64_t metricId = 1;
1498 Alert alert;
1499 alert.set_id(123);
1500 alert.set_metric_id(metricId);
1501 alert.set_trigger_if_sum_gt(1);
1502
1503 CountMetric metric;
1504 metric.set_id(metricId);
1505 metric.set_bucket(ONE_MINUTE);
1506 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1507 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1508 vector<sp<MetricProducer>> metricProducers(
1509 {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1510 0x0123456789, 0, 0, provider)});
1511 sp<AlarmMonitor> anomalyAlarmMonitor;
1512 optional<InvalidConfigReason> invalidConfigReason;
1513 EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1514 {{1, 0}}, metricProducers, invalidConfigReason),
1515 nullopt);
1516 EXPECT_EQ(invalidConfigReason,
1517 createInvalidConfigReasonWithAlert(
1518 INVALID_CONFIG_REASON_ALERT_INVALID_TRIGGER_OR_NUM_BUCKETS, alert.id()));
1519 }
1520
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerGood)1521 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerGood) {
1522 int64_t metricId = 1;
1523 Alert alert;
1524 alert.set_id(123);
1525 alert.set_metric_id(metricId);
1526 alert.set_trigger_if_sum_gt(1);
1527 alert.set_num_buckets(1);
1528
1529 CountMetric metric;
1530 metric.set_id(metricId);
1531 metric.set_bucket(ONE_MINUTE);
1532 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1533 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1534 vector<sp<MetricProducer>> metricProducers(
1535 {new CountMetricProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
1536 0x0123456789, 0, 0, provider)});
1537 sp<AlarmMonitor> anomalyAlarmMonitor;
1538 optional<InvalidConfigReason> invalidConfigReason;
1539 EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1540 {{1, 0}}, metricProducers, invalidConfigReason),
1541 nullopt);
1542 EXPECT_EQ(invalidConfigReason, nullopt);
1543 }
1544
TEST_F(MetricsManagerUtilTest,TestCreateAnomalyTrackerDurationTooLong)1545 TEST_F(MetricsManagerUtilTest, TestCreateAnomalyTrackerDurationTooLong) {
1546 int64_t metricId = 1;
1547 Alert alert;
1548 alert.set_id(123);
1549 alert.set_metric_id(metricId);
1550 // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
1551 alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
1552 alert.set_num_buckets(1);
1553
1554 DurationMetric metric;
1555 metric.set_id(metricId);
1556 metric.set_bucket(ONE_MINUTE);
1557 metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
1558 FieldMatcher dimensions;
1559 sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
1560 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1561 vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
1562 kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
1563 1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
1564 wizard, 0x0123456789, dimensions, 0, 0, provider)});
1565 sp<AlarmMonitor> anomalyAlarmMonitor;
1566 optional<InvalidConfigReason> invalidConfigReason;
1567 EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, UPDATE_NEW, /*updateTime=*/123,
1568 {{1, 0}}, metricProducers, invalidConfigReason),
1569 nullopt);
1570 EXPECT_EQ(invalidConfigReason,
1571 createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_CANNOT_ADD_ANOMALY,
1572 alert.metric_id(), alert.id()));
1573 }
1574
TEST_F(MetricsManagerUtilTest,TestCreateDurationProducerDimensionsInWhatInvalid)1575 TEST_F(MetricsManagerUtilTest, TestCreateDurationProducerDimensionsInWhatInvalid) {
1576 StatsdConfig config;
1577 *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1578 *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1579 *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
1580 *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
1581
1582 Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1583 // The predicate is dimensioning by first attribution node by uid.
1584 FieldMatcher dimensions =
1585 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1586 *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
1587 *config.add_predicate() = holdingWakelockPredicate;
1588
1589 DurationMetric* durationMetric = config.add_duration_metric();
1590 durationMetric->set_id(StringToId("WakelockDuration"));
1591 durationMetric->set_what(holdingWakelockPredicate.id());
1592 durationMetric->set_aggregation_type(DurationMetric::SUM);
1593 // The metric is dimensioning by first attribution node by uid AND tag.
1594 // Invalid since the predicate only dimensions by uid.
1595 *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
1596 util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
1597 durationMetric->set_bucket(FIVE_MINUTES);
1598
1599 ConfigKey key(123, 987);
1600 uint64_t timeNs = 456;
1601 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1602 sp<AlarmMonitor> anomalyAlarmMonitor;
1603 sp<AlarmMonitor> periodicAlarmMonitor;
1604 sp<UidMap> uidMap;
1605 sp<MetricsManager> metricsManager =
1606 new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1607 anomalyAlarmMonitor, periodicAlarmMonitor);
1608 EXPECT_FALSE(metricsManager->isConfigValid());
1609 }
1610
TEST_F(MetricsManagerUtilTest,TestSampledMetrics)1611 TEST_F(MetricsManagerUtilTest, TestSampledMetrics) {
1612 StatsdConfig config;
1613
1614 AtomMatcher appCrashMatcher =
1615 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1616 *config.add_atom_matcher() = appCrashMatcher;
1617
1618 *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1619 *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1620
1621 AtomMatcher bleScanResultReceivedMatcher = CreateSimpleAtomMatcher(
1622 "BleScanResultReceivedAtomMatcher", util::BLE_SCAN_RESULT_RECEIVED);
1623 *config.add_atom_matcher() = bleScanResultReceivedMatcher;
1624
1625 Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1626 *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
1627 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1628 *config.add_predicate() = holdingWakelockPredicate;
1629
1630 CountMetric sampledCountMetric =
1631 createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1632 *sampledCountMetric.mutable_dimensions_in_what() =
1633 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1634 *sampledCountMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1635 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1636 sampledCountMetric.mutable_dimensional_sampling_info()->set_shard_count(2);
1637 *config.add_count_metric() = sampledCountMetric;
1638
1639 CountMetric unsampledCountMetric =
1640 createCountMetric("CountAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1641 *unsampledCountMetric.mutable_dimensions_in_what() =
1642 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1643 *config.add_count_metric() = unsampledCountMetric;
1644
1645 DurationMetric sampledDurationMetric = createDurationMetric(
1646 "DurationSampledWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1647 *sampledDurationMetric.mutable_dimensions_in_what() =
1648 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1649 *sampledDurationMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1650 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1651 sampledDurationMetric.mutable_dimensional_sampling_info()->set_shard_count(4);
1652 *config.add_duration_metric() = sampledDurationMetric;
1653
1654 DurationMetric unsampledDurationMetric = createDurationMetric(
1655 "DurationWakelockPerUid", holdingWakelockPredicate.id(), nullopt, {});
1656 unsampledDurationMetric.set_aggregation_type(DurationMetric::SUM);
1657 *unsampledDurationMetric.mutable_dimensions_in_what() =
1658 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1659 *config.add_duration_metric() = unsampledDurationMetric;
1660
1661 ValueMetric sampledValueMetric =
1662 createValueMetric("ValueSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1663 /*num_results=*/2, nullopt, {});
1664 *sampledValueMetric.mutable_dimensions_in_what() =
1665 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1666 *sampledValueMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1667 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1668 sampledValueMetric.mutable_dimensional_sampling_info()->set_shard_count(6);
1669 *config.add_value_metric() = sampledValueMetric;
1670
1671 ValueMetric unsampledValueMetric =
1672 createValueMetric("ValueBleScanResultsPerUid", bleScanResultReceivedMatcher,
1673 /*num_results=*/2, nullopt, {});
1674 *unsampledValueMetric.mutable_dimensions_in_what() =
1675 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1676 *config.add_value_metric() = unsampledValueMetric;
1677
1678 KllMetric sampledKllMetric =
1679 createKllMetric("KllSampledBleScanResultsPerUid", bleScanResultReceivedMatcher,
1680 /*num_results=*/2, nullopt);
1681 *sampledKllMetric.mutable_dimensions_in_what() =
1682 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1683 *sampledKllMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1684 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /*uid*/});
1685 sampledKllMetric.mutable_dimensional_sampling_info()->set_shard_count(8);
1686 *config.add_kll_metric() = sampledKllMetric;
1687
1688 KllMetric unsampledKllMetric = createKllMetric(
1689 "KllBleScanResultsPerUid", bleScanResultReceivedMatcher, /*num_results=*/2, nullopt);
1690 *unsampledKllMetric.mutable_dimensions_in_what() =
1691 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
1692 *config.add_kll_metric() = unsampledKllMetric;
1693
1694 GaugeMetric sampledGaugeMetric =
1695 createGaugeMetric("GaugeSampledAppCrashesPerUid", appCrashMatcher.id(),
1696 GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1697 *sampledGaugeMetric.mutable_dimensions_in_what() =
1698 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1699 *sampledGaugeMetric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1700 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1701 sampledGaugeMetric.mutable_dimensional_sampling_info()->set_shard_count(10);
1702 *config.add_gauge_metric() = sampledGaugeMetric;
1703
1704 GaugeMetric unsampledGaugeMetric =
1705 createGaugeMetric("GaugeAppCrashesPerUid", appCrashMatcher.id(),
1706 GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
1707 *unsampledGaugeMetric.mutable_dimensions_in_what() =
1708 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
1709 *config.add_gauge_metric() = unsampledGaugeMetric;
1710
1711 ConfigKey key(123, 987);
1712 uint64_t timeNs = 456;
1713 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
1714 sp<AlarmMonitor> anomalyAlarmMonitor;
1715 sp<AlarmMonitor> periodicAlarmMonitor;
1716 sp<UidMap> uidMap;
1717 sp<MetricsManager> metricsManager =
1718 new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
1719 anomalyAlarmMonitor, periodicAlarmMonitor);
1720 ASSERT_TRUE(metricsManager->isConfigValid());
1721 ASSERT_EQ(10, metricsManager->mAllMetricProducers.size());
1722
1723 sp<MetricProducer> sampledCountMetricProducer = metricsManager->mAllMetricProducers[0];
1724 sp<MetricProducer> unsampledCountMetricProducer = metricsManager->mAllMetricProducers[1];
1725 sp<MetricProducer> sampledDurationMetricProducer = metricsManager->mAllMetricProducers[2];
1726 sp<MetricProducer> unsampledDurationMetricProducer = metricsManager->mAllMetricProducers[3];
1727 sp<MetricProducer> sampledValueMetricProducer = metricsManager->mAllMetricProducers[4];
1728 sp<MetricProducer> unsampledValueMetricProducer = metricsManager->mAllMetricProducers[5];
1729 sp<MetricProducer> sampledKllMetricProducer = metricsManager->mAllMetricProducers[6];
1730 sp<MetricProducer> unsampledKllMetricProducer = metricsManager->mAllMetricProducers[7];
1731 sp<MetricProducer> sampledGaugeMetricProducer = metricsManager->mAllMetricProducers[8];
1732 sp<MetricProducer> unsampledGaugeMetricProducer = metricsManager->mAllMetricProducers[9];
1733
1734 // Check shard count is set correctly for sampled metrics or set to default.
1735 EXPECT_EQ(2, sampledCountMetricProducer->mShardCount);
1736 EXPECT_EQ(0, unsampledCountMetricProducer->mShardCount);
1737 EXPECT_EQ(4, sampledDurationMetricProducer->mShardCount);
1738 EXPECT_EQ(0, unsampledDurationMetricProducer->mShardCount);
1739 EXPECT_EQ(6, sampledValueMetricProducer->mShardCount);
1740 EXPECT_EQ(0, unsampledValueMetricProducer->mShardCount);
1741 EXPECT_EQ(8, sampledKllMetricProducer->mShardCount);
1742 EXPECT_EQ(0, unsampledKllMetricProducer->mShardCount);
1743 EXPECT_EQ(10, sampledGaugeMetricProducer->mShardCount);
1744 EXPECT_EQ(0, unsampledGaugeMetricProducer->mShardCount);
1745
1746 // Check sampled what fields is set correctly or empty.
1747 EXPECT_EQ(1, sampledCountMetricProducer->mSampledWhatFields.size());
1748 EXPECT_EQ(true, unsampledCountMetricProducer->mSampledWhatFields.empty());
1749 EXPECT_EQ(1, sampledDurationMetricProducer->mSampledWhatFields.size());
1750 EXPECT_EQ(true, unsampledDurationMetricProducer->mSampledWhatFields.empty());
1751 EXPECT_EQ(1, sampledValueMetricProducer->mSampledWhatFields.size());
1752 EXPECT_EQ(true, unsampledValueMetricProducer->mSampledWhatFields.empty());
1753 EXPECT_EQ(1, sampledKllMetricProducer->mSampledWhatFields.size());
1754 EXPECT_EQ(true, unsampledKllMetricProducer->mSampledWhatFields.empty());
1755 EXPECT_EQ(1, sampledGaugeMetricProducer->mSampledWhatFields.size());
1756 EXPECT_EQ(true, unsampledGaugeMetricProducer->mSampledWhatFields.empty());
1757 }
1758
TEST_F(MetricsManagerUtilTest,TestMetricHasShardCountButNoSampledField)1759 TEST_F(MetricsManagerUtilTest, TestMetricHasShardCountButNoSampledField) {
1760 AtomMatcher appCrashMatcher =
1761 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1762
1763 StatsdConfig config;
1764 *config.add_atom_matcher() = appCrashMatcher;
1765
1766 CountMetric metric =
1767 createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1768 *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1769 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1770 *config.add_count_metric() = metric;
1771
1772 EXPECT_EQ(initConfig(config),
1773 InvalidConfigReason(
1774 INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_MISSING_SAMPLED_FIELD,
1775 metric.id()));
1776 }
1777
TEST_F(MetricsManagerUtilTest,TestMetricHasSampledFieldIncorrectShardCount)1778 TEST_F(MetricsManagerUtilTest, TestMetricHasSampledFieldIncorrectShardCount) {
1779 AtomMatcher appCrashMatcher =
1780 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1781
1782 StatsdConfig config;
1783 *config.add_atom_matcher() = appCrashMatcher;
1784
1785 CountMetric metric =
1786 createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1787 *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1788 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1789 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1790 *config.add_count_metric() = metric;
1791
1792 EXPECT_EQ(initConfig(config),
1793 InvalidConfigReason(
1794 INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_INCORRECT_SHARD_COUNT,
1795 metric.id()));
1796 }
1797
TEST_F(MetricsManagerUtilTest,TestMetricHasMultipleSampledFields)1798 TEST_F(MetricsManagerUtilTest, TestMetricHasMultipleSampledFields) {
1799 AtomMatcher appCrashMatcher =
1800 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1801
1802 StatsdConfig config;
1803 *config.add_atom_matcher() = appCrashMatcher;
1804
1805 CountMetric metric =
1806 createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1807 *metric.mutable_dimensions_in_what() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1808 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1809 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/, 2 /*event_type*/});
1810 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1811 *config.add_count_metric() = metric;
1812
1813 EXPECT_EQ(initConfig(config),
1814 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1815 metric.id()));
1816 }
1817
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionALL)1818 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionALL) {
1819 AtomMatcher testAtomReportedMatcher =
1820 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1821
1822 StatsdConfig config;
1823 *config.add_atom_matcher() = testAtomReportedMatcher;
1824
1825 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1826 testAtomReportedMatcher.id(), nullopt, {});
1827 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1828 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
1829 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1830 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1831 {Position::ALL});
1832 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1833 *config.add_count_metric() = metric;
1834
1835 EXPECT_EQ(initConfig(config),
1836 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1837 metric.id()));
1838 }
1839
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_PositionANY)1840 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_PositionANY) {
1841 AtomMatcher testAtomReportedMatcher =
1842 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1843
1844 StatsdConfig config;
1845 *config.add_atom_matcher() = testAtomReportedMatcher;
1846
1847 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1848 testAtomReportedMatcher.id(), nullopt, {});
1849 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1850 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ANY});
1851 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1852 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1853 {Position::ANY});
1854 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1855 *config.add_count_metric() = metric;
1856
1857 EXPECT_EQ(initConfig(config),
1858 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
1859 metric.id()));
1860 }
1861
TEST_F(MetricsManagerUtilTest,TestMetricSampledField_DifferentFieldsNotSubsetDimension)1862 TEST_F(MetricsManagerUtilTest, TestMetricSampledField_DifferentFieldsNotSubsetDimension) {
1863 AtomMatcher appCrashMatcher =
1864 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
1865
1866 StatsdConfig config;
1867 *config.add_atom_matcher() = appCrashMatcher;
1868
1869 CountMetric metric =
1870 createCountMetric("CountSampledAppCrashesPerUid", appCrashMatcher.id(), nullopt, {});
1871 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1872 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
1873 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1874 *config.add_count_metric() = metric;
1875
1876 EXPECT_EQ(
1877 initConfig(config),
1878 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1879 metric.id()));
1880 }
1881
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastNotSubsetDimensionsFirst)1882 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastNotSubsetDimensionsFirst) {
1883 AtomMatcher testAtomReportedMatcher =
1884 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1885
1886 StatsdConfig config;
1887 *config.add_atom_matcher() = testAtomReportedMatcher;
1888
1889 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1890 testAtomReportedMatcher.id(), nullopt, {});
1891 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1892 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::FIRST});
1893 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1894 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1895 {Position::LAST});
1896 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1897 *config.add_count_metric() = metric;
1898
1899 EXPECT_EQ(
1900 initConfig(config),
1901 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1902 metric.id()));
1903 }
1904
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstNotSubsetDimensionsLast)1905 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstNotSubsetDimensionsLast) {
1906 AtomMatcher testAtomReportedMatcher =
1907 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1908
1909 StatsdConfig config;
1910 *config.add_atom_matcher() = testAtomReportedMatcher;
1911
1912 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1913 testAtomReportedMatcher.id(), nullopt, {});
1914 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1915 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::LAST});
1916 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1917 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1918 {Position::FIRST});
1919 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1920 *config.add_count_metric() = metric;
1921
1922 EXPECT_EQ(
1923 initConfig(config),
1924 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT,
1925 metric.id()));
1926 }
1927
1928 // dimensions_in_what position ALL, sampled_what_field position FIRST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstSubsetDimensionsAll)1929 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstSubsetDimensionsAll) {
1930 AtomMatcher testAtomReportedMatcher =
1931 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1932
1933 StatsdConfig config;
1934 *config.add_atom_matcher() = testAtomReportedMatcher;
1935
1936 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1937 testAtomReportedMatcher.id(), nullopt, {});
1938 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1939 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
1940 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1941 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1942 {Position::FIRST});
1943 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1944 *config.add_count_metric() = metric;
1945 EXPECT_EQ(initConfig(config), nullopt);
1946 }
1947
1948 // dimensions_in_what position ALL, sampled_what_field position LAST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastSubsetDimensionsAll)1949 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastSubsetDimensionsAll) {
1950 AtomMatcher testAtomReportedMatcher =
1951 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1952
1953 StatsdConfig config;
1954 *config.add_atom_matcher() = testAtomReportedMatcher;
1955
1956 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1957 testAtomReportedMatcher.id(), nullopt, {});
1958 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1959 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
1960 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1961 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1962 {Position::LAST});
1963 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1964 *config.add_count_metric() = metric;
1965 EXPECT_EQ(initConfig(config), nullopt);
1966 }
1967
1968 // dimensions_in_what position FIRST, sampled_what_field position FIRST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_FirstSubsetDimensionsFirst)1969 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_FirstSubsetDimensionsFirst) {
1970 AtomMatcher testAtomReportedMatcher =
1971 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1972
1973 StatsdConfig config;
1974 *config.add_atom_matcher() = testAtomReportedMatcher;
1975
1976 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1977 testAtomReportedMatcher.id(), nullopt, {});
1978 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1979 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::FIRST});
1980 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
1981 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
1982 {Position::FIRST});
1983 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
1984 *config.add_count_metric() = metric;
1985 EXPECT_EQ(initConfig(config), nullopt);
1986 }
1987
1988 // dimensions_in_what position LAST, sampled_what_field position LAST
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedSampledField_LastSubsetDimensionsLast)1989 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedSampledField_LastSubsetDimensionsLast) {
1990 AtomMatcher testAtomReportedMatcher =
1991 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
1992
1993 StatsdConfig config;
1994 *config.add_atom_matcher() = testAtomReportedMatcher;
1995
1996 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
1997 testAtomReportedMatcher.id(), nullopt, {});
1998 *metric.mutable_dimensions_in_what() = CreateRepeatedDimensions(
1999 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::LAST});
2000 *metric.mutable_dimensional_sampling_info()->mutable_sampled_what_field() =
2001 CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/},
2002 {Position::LAST});
2003 metric.mutable_dimensional_sampling_info()->set_shard_count(2);
2004 *config.add_count_metric() = metric;
2005 EXPECT_EQ(initConfig(config), nullopt);
2006 }
2007
TEST_F(MetricsManagerUtilTest,TestCountMetricHasRestrictedDelegate)2008 TEST_F(MetricsManagerUtilTest, TestCountMetricHasRestrictedDelegate) {
2009 StatsdConfig config;
2010 CountMetric* metric = config.add_count_metric();
2011 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2012
2013 EXPECT_EQ(initConfig(config),
2014 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2015 }
2016
TEST_F(MetricsManagerUtilTest,TestDurationMetricHasRestrictedDelegate)2017 TEST_F(MetricsManagerUtilTest, TestDurationMetricHasRestrictedDelegate) {
2018 StatsdConfig config;
2019 DurationMetric* metric = config.add_duration_metric();
2020 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2021
2022 EXPECT_EQ(initConfig(config),
2023 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2024 }
2025
TEST_F(MetricsManagerUtilTest,TestGaugeMetricHasRestrictedDelegate)2026 TEST_F(MetricsManagerUtilTest, TestGaugeMetricHasRestrictedDelegate) {
2027 StatsdConfig config;
2028 GaugeMetric* metric = config.add_gauge_metric();
2029 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2030
2031 EXPECT_EQ(initConfig(config),
2032 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2033 }
2034
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHasRestrictedDelegate)2035 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHasRestrictedDelegate) {
2036 StatsdConfig config;
2037 ValueMetric* metric = config.add_value_metric();
2038 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2039
2040 EXPECT_EQ(initConfig(config),
2041 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2042 }
2043
TEST_F(MetricsManagerUtilTest,TestKllMetricHasRestrictedDelegate)2044 TEST_F(MetricsManagerUtilTest, TestKllMetricHasRestrictedDelegate) {
2045 StatsdConfig config;
2046 KllMetric* metric = config.add_kll_metric();
2047 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
2048
2049 EXPECT_EQ(initConfig(config),
2050 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
2051 }
2052
TEST_P(MetricsManagerUtilDimLimitTest,TestDimLimit)2053 TEST_P(MetricsManagerUtilDimLimitTest, TestDimLimit) {
2054 StatsdConfig config = buildGoodConfig(kConfigId, kAlertId);
2055 const auto& [configLimit, actualLimit] = GetParam();
2056 if (configLimit > 0) {
2057 config.mutable_count_metric(0)->set_max_dimensions_per_bucket(configLimit);
2058 config.mutable_duration_metric(0)->set_max_dimensions_per_bucket(configLimit);
2059 config.mutable_gauge_metric(0)->set_max_dimensions_per_bucket(configLimit);
2060 config.mutable_value_metric(0)->set_max_dimensions_per_bucket(configLimit);
2061 config.mutable_kll_metric(0)->set_max_dimensions_per_bucket(configLimit);
2062 }
2063
2064 // initConfig returns nullopt if config is valid
2065 EXPECT_EQ(initConfig(config), nullopt);
2066 ASSERT_EQ(5u, allMetricProducers.size());
2067
2068 sp<MetricProducer> producer =
2069 allMetricProducers[metricProducerMap.at(config.count_metric(0).id())];
2070 CountMetricProducer* countProducer = static_cast<CountMetricProducer*>(producer.get());
2071 EXPECT_EQ(countProducer->mDimensionHardLimit, actualLimit);
2072
2073 producer = allMetricProducers[metricProducerMap.at(config.duration_metric(0).id())];
2074 DurationMetricProducer* durationProducer = static_cast<DurationMetricProducer*>(producer.get());
2075 EXPECT_EQ(durationProducer->mDimensionHardLimit, actualLimit);
2076
2077 producer = allMetricProducers[metricProducerMap.at(config.gauge_metric(0).id())];
2078 GaugeMetricProducer* gaugeProducer = static_cast<GaugeMetricProducer*>(producer.get());
2079 EXPECT_EQ(gaugeProducer->mDimensionHardLimit, actualLimit);
2080
2081 producer = allMetricProducers[metricProducerMap.at(config.value_metric(0).id())];
2082 NumericValueMetricProducer* numericValueProducer =
2083 static_cast<NumericValueMetricProducer*>(producer.get());
2084 EXPECT_EQ(numericValueProducer->mDimensionHardLimit, actualLimit);
2085
2086 producer = allMetricProducers[metricProducerMap.at(config.kll_metric(0).id())];
2087 KllMetricProducer* kllProducer = static_cast<KllMetricProducer*>(producer.get());
2088 EXPECT_EQ(kllProducer->mDimensionHardLimit, actualLimit);
2089 }
2090
TEST_F(MetricsManagerUtilTest,TestMissingValueMatcherAndStringReplacer)2091 TEST_F(MetricsManagerUtilTest, TestMissingValueMatcherAndStringReplacer) {
2092 StatsdConfig config;
2093 config.set_id(12345);
2094
2095 AtomMatcher* matcher = config.add_atom_matcher();
2096 matcher->set_id(111);
2097 matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2098 matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2099
2100 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2101
2102 ASSERT_NE(actualInvalidConfigReason, nullopt);
2103 EXPECT_EQ(actualInvalidConfigReason->reason,
2104 INVALID_CONFIG_REASON_MATCHER_NO_VALUE_MATCHER_NOR_STRING_REPLACER);
2105 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2106 }
2107
TEST_F(MetricsManagerUtilTest,TestMatcherWithValueMatcherOnly)2108 TEST_F(MetricsManagerUtilTest, TestMatcherWithValueMatcherOnly) {
2109 StatsdConfig config;
2110 config.set_id(12345);
2111
2112 AtomMatcher* matcher = config.add_atom_matcher();
2113 matcher->set_id(111);
2114 matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2115 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2116 fvm->set_field(2 /*int_field*/);
2117 fvm->set_eq_int(1);
2118
2119 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2120
2121 ASSERT_EQ(actualInvalidConfigReason, nullopt);
2122 }
2123
TEST_F(MetricsManagerUtilTest,TestMatcherWithStringReplacerOnly)2124 TEST_F(MetricsManagerUtilTest, TestMatcherWithStringReplacerOnly) {
2125 StatsdConfig config;
2126 config.set_id(12345);
2127
2128 AtomMatcher* matcher = config.add_atom_matcher();
2129 matcher->set_id(111);
2130 matcher->mutable_simple_atom_matcher()->set_atom_id(SCREEN_STATE_ATOM_ID);
2131 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2132 fvm->set_field(5 /*string_field*/);
2133 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2134 fvm->mutable_replace_string()->set_replacement("#");
2135
2136 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2137
2138 ASSERT_EQ(actualInvalidConfigReason, nullopt);
2139 }
2140
TEST_F(MetricsManagerUtilTest,TestValueMatcherWithPositionAll)2141 TEST_F(MetricsManagerUtilTest, TestValueMatcherWithPositionAll) {
2142 StatsdConfig config;
2143 config.set_id(12345);
2144
2145 AtomMatcher* matcher = config.add_atom_matcher();
2146 matcher->set_id(111);
2147 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2148 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2149 fvm->set_field(9 /*repeated_int_field*/);
2150 fvm->set_position(Position::ALL);
2151 fvm->set_eq_int(1);
2152
2153 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2154
2155 ASSERT_NE(actualInvalidConfigReason, nullopt);
2156 EXPECT_EQ(actualInvalidConfigReason->reason,
2157 INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2158 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2159 }
2160
TEST_F(MetricsManagerUtilTest,TestValueMatcherAndStringReplaceWithPositionAll)2161 TEST_F(MetricsManagerUtilTest, TestValueMatcherAndStringReplaceWithPositionAll) {
2162 StatsdConfig config;
2163 config.set_id(12345);
2164
2165 AtomMatcher* matcher = config.add_atom_matcher();
2166 matcher->set_id(111);
2167 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2168 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2169 fvm->set_field(12 /*repeated_string_field*/);
2170 fvm->set_position(Position::ALL);
2171 fvm->set_eq_string("foo");
2172 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2173 fvm->mutable_replace_string()->set_replacement("");
2174
2175 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2176
2177 ASSERT_NE(actualInvalidConfigReason, nullopt);
2178 EXPECT_EQ(actualInvalidConfigReason->reason,
2179 INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2180 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2181 }
2182
TEST_F(MetricsManagerUtilTest,TestValueMatcherWithPositionAllNested)2183 TEST_F(MetricsManagerUtilTest, TestValueMatcherWithPositionAllNested) {
2184 StatsdConfig config;
2185 config.set_id(12345);
2186
2187 // Match on attribution_node[ALL].uid = 1
2188 AtomMatcher* matcher = config.add_atom_matcher();
2189 matcher->set_id(111);
2190 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2191 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2192 fvm->set_field(1 /*attribution_node*/);
2193 fvm->set_position(Position::ALL);
2194 fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(1 /* uid */);
2195 fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_int(1);
2196
2197 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2198
2199 ASSERT_NE(actualInvalidConfigReason, nullopt);
2200 EXPECT_EQ(actualInvalidConfigReason->reason,
2201 INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2202 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2203 }
2204
TEST_F(MetricsManagerUtilTest,TestValueMatcherAndStringReplaceWithPositionAllNested)2205 TEST_F(MetricsManagerUtilTest, TestValueMatcherAndStringReplaceWithPositionAllNested) {
2206 StatsdConfig config;
2207 config.set_id(12345);
2208
2209 // Match on attribution_node[ALL].uid = 1
2210 AtomMatcher* matcher = config.add_atom_matcher();
2211 matcher->set_id(111);
2212 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2213 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2214 fvm->set_field(1 /*attribution_node*/);
2215 fvm->set_position(Position::ALL);
2216 fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2217 fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("foo");
2218 fvm->mutable_matches_tuple()
2219 ->mutable_field_value_matcher(0)
2220 ->mutable_replace_string()
2221 ->set_regex(R"([0-9]+$)");
2222 fvm->mutable_matches_tuple()
2223 ->mutable_field_value_matcher(0)
2224 ->mutable_replace_string()
2225 ->set_replacement("");
2226
2227 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2228
2229 ASSERT_NE(actualInvalidConfigReason, nullopt);
2230 EXPECT_EQ(actualInvalidConfigReason->reason,
2231 INVALID_CONFIG_REASON_MATCHER_VALUE_MATCHER_WITH_POSITION_ALL);
2232 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2233 }
2234
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithNoValueMatcherWithPositionAny)2235 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithNoValueMatcherWithPositionAny) {
2236 StatsdConfig config;
2237 config.set_id(12345);
2238
2239 AtomMatcher* matcher = config.add_atom_matcher();
2240 matcher->set_id(111);
2241 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2242 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2243 fvm->set_field(12 /*repeated_string_field*/);
2244 fvm->set_position(Position::ANY);
2245 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2246 fvm->mutable_replace_string()->set_replacement("");
2247
2248 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2249
2250 ASSERT_NE(actualInvalidConfigReason, nullopt);
2251 EXPECT_EQ(actualInvalidConfigReason->reason,
2252 INVALID_CONFIG_REASON_MATCHER_STRING_REPLACE_WITH_NO_VALUE_MATCHER_WITH_POSITION_ANY);
2253 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2254 }
2255
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithNoValueMatcherWithPositionAnyNested)2256 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithNoValueMatcherWithPositionAnyNested) {
2257 StatsdConfig config;
2258 config.set_id(12345);
2259
2260 // Match on attribution_node[ALL].uid = 1
2261 AtomMatcher* matcher = config.add_atom_matcher();
2262 matcher->set_id(111);
2263 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2264 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2265 fvm->set_field(1 /*attribution_node*/);
2266 fvm->set_position(Position::ANY);
2267 fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2268 fvm->mutable_matches_tuple()
2269 ->mutable_field_value_matcher(0)
2270 ->mutable_replace_string()
2271 ->set_regex(R"([0-9]+$)");
2272 fvm->mutable_matches_tuple()
2273 ->mutable_field_value_matcher(0)
2274 ->mutable_replace_string()
2275 ->set_replacement("");
2276
2277 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2278
2279 ASSERT_NE(actualInvalidConfigReason, nullopt);
2280 EXPECT_EQ(actualInvalidConfigReason->reason,
2281 INVALID_CONFIG_REASON_MATCHER_STRING_REPLACE_WITH_NO_VALUE_MATCHER_WITH_POSITION_ANY);
2282 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2283 }
2284
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithValueMatcherWithPositionAny)2285 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithValueMatcherWithPositionAny) {
2286 StatsdConfig config;
2287 config.set_id(12345);
2288
2289 AtomMatcher* matcher = config.add_atom_matcher();
2290 matcher->set_id(111);
2291 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2292 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2293 fvm->set_field(12 /*repeated_string_field*/);
2294 fvm->set_position(Position::ANY);
2295 fvm->set_eq_string("bar");
2296 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2297 fvm->mutable_replace_string()->set_replacement("");
2298
2299 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2300
2301 ASSERT_EQ(actualInvalidConfigReason, nullopt);
2302 }
2303
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithValueMatcherWithPositionAnyNested)2304 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithValueMatcherWithPositionAnyNested) {
2305 StatsdConfig config;
2306 config.set_id(12345);
2307
2308 // Match on attribution_node[ALL].uid = 1
2309 AtomMatcher* matcher = config.add_atom_matcher();
2310 matcher->set_id(111);
2311 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2312 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2313 fvm->set_field(1 /*attribution_node*/);
2314 fvm->set_position(Position::ANY);
2315 fvm->mutable_matches_tuple()->add_field_value_matcher()->set_field(2 /* tag */);
2316 fvm->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("bar");
2317 fvm->mutable_matches_tuple()
2318 ->mutable_field_value_matcher(0)
2319 ->mutable_replace_string()
2320 ->set_regex(R"([0-9]+$)");
2321 fvm->mutable_matches_tuple()
2322 ->mutable_field_value_matcher(0)
2323 ->mutable_replace_string()
2324 ->set_replacement("");
2325
2326 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2327
2328 ASSERT_EQ(actualInvalidConfigReason, nullopt);
2329 }
2330
TEST_F(MetricsManagerUtilTest,TestStringReplaceWithPositionAllNested)2331 TEST_F(MetricsManagerUtilTest, TestStringReplaceWithPositionAllNested) {
2332 StatsdConfig config;
2333 config.set_id(12345);
2334
2335 // Replace attribution_node[ALL].tag using "[0-9]+$" -> "".
2336 AtomMatcher* matcher = config.add_atom_matcher();
2337 matcher->set_id(111);
2338 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2339 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2340 fvm->set_field(1 /*attribution_node*/);
2341 fvm->set_position(Position::ALL);
2342 fvm = fvm->mutable_matches_tuple()->add_field_value_matcher();
2343 fvm->set_field(2 /* tag */);
2344 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2345 fvm->mutable_replace_string()->set_replacement("");
2346
2347 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2348
2349 ASSERT_EQ(actualInvalidConfigReason, nullopt);
2350 }
2351
TEST_F(MetricsManagerUtilTest,TestMatcherWithStringReplaceAndNonStringValueMatcher)2352 TEST_F(MetricsManagerUtilTest, TestMatcherWithStringReplaceAndNonStringValueMatcher) {
2353 StatsdConfig config;
2354 config.set_id(12345);
2355
2356 AtomMatcher* matcher = config.add_atom_matcher();
2357 matcher->set_id(111);
2358 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2359 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2360 fvm->set_field(2 /*int_field*/);
2361 fvm->set_eq_int(1);
2362 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2363 fvm->mutable_replace_string()->set_replacement("#");
2364
2365 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2366
2367 ASSERT_NE(actualInvalidConfigReason, nullopt);
2368 EXPECT_EQ(actualInvalidConfigReason->reason,
2369 INVALID_CONFIG_REASON_MATCHER_INVALID_VALUE_MATCHER_WITH_STRING_REPLACE);
2370 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(111));
2371 }
2372
TEST_F(MetricsManagerUtilTest,TestCombinationMatcherWithStringReplace)2373 TEST_F(MetricsManagerUtilTest, TestCombinationMatcherWithStringReplace) {
2374 StatsdConfig config;
2375 config.set_id(12345);
2376
2377 AtomMatcher* matcher = config.add_atom_matcher();
2378 matcher->set_id(111);
2379 matcher->mutable_simple_atom_matcher()->set_atom_id(util::TEST_ATOM_REPORTED);
2380 FieldValueMatcher* fvm = matcher->mutable_simple_atom_matcher()->add_field_value_matcher();
2381 fvm->set_field(5 /*string_field*/);
2382 fvm->mutable_replace_string()->set_regex(R"([0-9]+$)");
2383 fvm->mutable_replace_string()->set_replacement("#");
2384
2385 matcher = config.add_atom_matcher();
2386 matcher->set_id(222);
2387 matcher->mutable_combination()->set_operation(LogicalOperation::NOT);
2388 matcher->mutable_combination()->add_matcher(111);
2389
2390 optional<InvalidConfigReason> actualInvalidConfigReason = initConfig(config);
2391
2392 ASSERT_NE(actualInvalidConfigReason, nullopt);
2393 EXPECT_EQ(actualInvalidConfigReason->reason,
2394 INVALID_CONFIG_REASON_MATCHER_COMBINATION_WITH_STRING_REPLACE);
2395 EXPECT_THAT(actualInvalidConfigReason->matcherIds, ElementsAre(222));
2396 }
2397
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMissingHistogramBinConfigSingleAggType)2398 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMissingHistogramBinConfigSingleAggType) {
2399 StatsdConfig config = createHistogramStatsdConfig();
2400
2401 EXPECT_EQ(initConfig(config),
2402 InvalidConfigReason(
2403 INVALID_CONFIG_REASON_VALUE_METRIC_HIST_COUNT_DNE_HIST_BIN_CONFIGS_COUNT,
2404 config.value_metric(0).id()));
2405 }
2406
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricMissingHistogramBinConfigMultipleAggTypes)2407 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricMissingHistogramBinConfigMultipleAggTypes) {
2408 StatsdConfig config = createHistogramStatsdConfig();
2409 config.mutable_value_metric(0)->clear_aggregation_type();
2410 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::SUM);
2411 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::HISTOGRAM);
2412 config.mutable_value_metric(0)->mutable_value_field()->add_child()->set_field(2);
2413
2414 EXPECT_EQ(initConfig(config),
2415 InvalidConfigReason(
2416 INVALID_CONFIG_REASON_VALUE_METRIC_HIST_COUNT_DNE_HIST_BIN_CONFIGS_COUNT,
2417 config.value_metric(0).id()));
2418 }
2419
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricExtraHistogramBinConfig)2420 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricExtraHistogramBinConfig) {
2421 StatsdConfig config = createExplicitHistogramStatsdConfig({5, 10, 12});
2422 *config.mutable_value_metric(0)->add_histogram_bin_configs() =
2423 createExplicitBinConfig(/* id */ 1, /* bins */ {5, 10, 20});
2424
2425 EXPECT_EQ(initConfig(config),
2426 InvalidConfigReason(
2427 INVALID_CONFIG_REASON_VALUE_METRIC_HIST_COUNT_DNE_HIST_BIN_CONFIGS_COUNT,
2428 config.value_metric(0).id()));
2429 }
2430
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHistogramMultipleValueFields)2431 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHistogramMultipleValueFields) {
2432 StatsdConfig config = createExplicitHistogramStatsdConfig({5, 10, 12});
2433 config.mutable_value_metric(0)->mutable_value_field()->add_child()->set_field(2);
2434
2435 EXPECT_EQ(initConfig(config), nullopt);
2436 }
2437
TEST_F(MetricsManagerUtilTest,TestNumericValueMetricHistogramWithUploadThreshold)2438 TEST_F(MetricsManagerUtilTest, TestNumericValueMetricHistogramWithUploadThreshold) {
2439 StatsdConfig config = createExplicitHistogramStatsdConfig({5, 10, 12});
2440 config.mutable_value_metric(0)->mutable_threshold()->set_lt_float(1.0);
2441
2442 EXPECT_EQ(initConfig(config),
2443 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HIST_WITH_UPLOAD_THRESHOLD,
2444 config.value_metric(0).id()));
2445
2446 clearData();
2447 config.mutable_value_metric(0)->clear_aggregation_type();
2448 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::HISTOGRAM);
2449 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::SUM);
2450 config.mutable_value_metric(0)->mutable_value_field()->add_child()->set_field(2);
2451
2452 EXPECT_EQ(initConfig(config),
2453 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HIST_WITH_UPLOAD_THRESHOLD,
2454 config.value_metric(0).id()));
2455 }
2456
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasPositionAllWithStatsdAggregatedHistogram)2457 TEST_F(MetricsManagerUtilTest,
2458 TestValueMetricValueFieldHasPositionAllWithStatsdAggregatedHistogram) {
2459 StatsdConfig config = createExplicitHistogramStatsdConfig({5, 10, 12});
2460 config.mutable_value_metric(0)->mutable_value_field()->mutable_child(0)->set_position(ALL);
2461
2462 EXPECT_EQ(initConfig(config),
2463 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL,
2464 config.value_metric(0).id()));
2465
2466 clearData();
2467 config.mutable_value_metric(0)->clear_aggregation_type();
2468 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::HISTOGRAM);
2469 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::SUM);
2470 config.mutable_value_metric(0)->mutable_value_field()->add_child()->set_field(2);
2471
2472 EXPECT_EQ(initConfig(config),
2473 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL,
2474 config.value_metric(0).id()));
2475 }
2476
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasNoPositionAllWithClientAggregatedHistogram)2477 TEST_F(MetricsManagerUtilTest,
2478 TestValueMetricValueFieldHasNoPositionAllWithClientAggregatedHistogram) {
2479 StatsdConfig config = createHistogramStatsdConfig();
2480 config.mutable_value_metric(0)->add_histogram_bin_configs()->set_id(1);
2481 config.mutable_value_metric(0)
2482 ->mutable_histogram_bin_configs(0)
2483 ->mutable_client_aggregated_bins();
2484
2485 EXPECT_EQ(initConfig(config),
2486 InvalidConfigReason(
2487 INVALID_CONFIG_REASON_VALUE_METRIC_HIST_CLIENT_AGGREGATED_NO_POSITION_ALL,
2488 config.value_metric(0).id()));
2489 }
2490
TEST_F(MetricsManagerUtilTest,TestValueMetricValueFieldHasPositionAllWithClientAggregatedHistogram)2491 TEST_F(MetricsManagerUtilTest,
2492 TestValueMetricValueFieldHasPositionAllWithClientAggregatedHistogram) {
2493 StatsdConfig config = createHistogramStatsdConfig();
2494 config.mutable_value_metric(0)->add_histogram_bin_configs()->set_id(1);
2495 config.mutable_value_metric(0)
2496 ->mutable_histogram_bin_configs(0)
2497 ->mutable_client_aggregated_bins();
2498 config.mutable_value_metric(0)->mutable_value_field()->mutable_child(0)->set_position(ALL);
2499
2500 EXPECT_EQ(initConfig(config), nullopt);
2501 }
2502
TEST_F(MetricsManagerUtilTest,TestValueMetricHistogramWithValueDirectionNotIncreasing)2503 TEST_F(MetricsManagerUtilTest, TestValueMetricHistogramWithValueDirectionNotIncreasing) {
2504 StatsdConfig config = createHistogramStatsdConfig();
2505 config.mutable_value_metric(0)->mutable_value_field()->mutable_child(0)->set_position(ALL);
2506 config.mutable_value_metric(0)->add_histogram_bin_configs()->set_id(1);
2507 config.mutable_value_metric(0)
2508 ->mutable_histogram_bin_configs(0)
2509 ->mutable_client_aggregated_bins();
2510 config.mutable_value_metric(0)->set_value_direction(ValueMetric::DECREASING);
2511
2512 EXPECT_EQ(initConfig(config),
2513 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HIST_INVALID_VALUE_DIRECTION,
2514 config.value_metric(0).id()));
2515
2516 clearData();
2517 config.mutable_value_metric(0)->clear_aggregation_type();
2518 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::SUM);
2519 config.mutable_value_metric(0)->add_aggregation_types(ValueMetric::HISTOGRAM);
2520 config.mutable_value_metric(0)->mutable_value_field()->mutable_child(0)->clear_position();
2521 config.mutable_value_metric(0)->mutable_value_field()->add_child()->set_field(2);
2522 config.mutable_value_metric(0)->mutable_value_field()->mutable_child(1)->set_position(ALL);
2523 config.mutable_value_metric(0)->set_value_direction(ValueMetric::ANY);
2524
2525 EXPECT_EQ(initConfig(config),
2526 InvalidConfigReason(INVALID_CONFIG_REASON_VALUE_METRIC_HIST_INVALID_VALUE_DIRECTION,
2527 config.value_metric(0).id()));
2528 }
2529
TEST_F(MetricsManagerUtilTest,TestUidFields)2530 TEST_F(MetricsManagerUtilTest, TestUidFields) {
2531 StatsdConfig config;
2532
2533 AtomMatcher appCrashMatcher =
2534 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
2535 *config.add_atom_matcher() = appCrashMatcher;
2536
2537 *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
2538 *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
2539
2540 AtomMatcher bleScanResultReceivedMatcher =
2541 CreateSimpleAtomMatcher("Ble", util::BLE_SCAN_RESULT_RECEIVED);
2542 *config.add_atom_matcher() = bleScanResultReceivedMatcher;
2543
2544 Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
2545 *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
2546 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2547 *config.add_predicate() = holdingWakelockPredicate;
2548
2549 CountMetric uidCountMetric = createCountMetric("C1", appCrashMatcher.id(), nullopt, {});
2550 *uidCountMetric.mutable_uid_fields() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
2551 *config.add_count_metric() = uidCountMetric;
2552
2553 CountMetric countMetric = createCountMetric("C2", appCrashMatcher.id(), nullopt, {});
2554 *config.add_count_metric() = countMetric;
2555
2556 DurationMetric uidDurationMetric =
2557 createDurationMetric("D1", holdingWakelockPredicate.id(), nullopt, {});
2558 *uidDurationMetric.mutable_uid_fields() =
2559 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2560 *config.add_duration_metric() = uidDurationMetric;
2561
2562 DurationMetric durationMetric =
2563 createDurationMetric("D2", holdingWakelockPredicate.id(), nullopt, {});
2564 *config.add_duration_metric() = durationMetric;
2565
2566 EventMetric uidEventMetric = createEventMetric("E1", appCrashMatcher.id(), nullopt);
2567 *uidEventMetric.mutable_uid_fields() = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
2568 *config.add_event_metric() = uidEventMetric;
2569
2570 EventMetric eventMetric = createEventMetric("E2", appCrashMatcher.id(), nullopt);
2571 *config.add_event_metric() = eventMetric;
2572
2573 ValueMetric uidValueMetric = createValueMetric("V1", bleScanResultReceivedMatcher,
2574 /*num_results=*/2, nullopt, {});
2575 *uidValueMetric.mutable_uid_fields() =
2576 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
2577 *config.add_value_metric() = uidValueMetric;
2578
2579 ValueMetric valueMetric = createValueMetric("V2", bleScanResultReceivedMatcher,
2580 /*num_results=*/2, nullopt, {});
2581 *config.add_value_metric() = valueMetric;
2582
2583 KllMetric uidKllMetric = createKllMetric("K1", bleScanResultReceivedMatcher,
2584 /*num_results=*/2, nullopt);
2585 *uidKllMetric.mutable_uid_fields() =
2586 CreateDimensions(util::BLE_SCAN_RESULT_RECEIVED, {1 /* uid */});
2587 *config.add_kll_metric() = uidKllMetric;
2588
2589 KllMetric kllMetric =
2590 createKllMetric("K2", bleScanResultReceivedMatcher, /*num_results=*/2, nullopt);
2591 *config.add_kll_metric() = kllMetric;
2592
2593 GaugeMetric uidGaugeMetric = createGaugeMetric("G1", appCrashMatcher.id(),
2594 GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
2595 *uidGaugeMetric.mutable_uid_fields() =
2596 CreateDimensions(util::APP_CRASH_OCCURRED, {1 /* uid */});
2597 *config.add_gauge_metric() = uidGaugeMetric;
2598
2599 GaugeMetric gaugeMetric = createGaugeMetric("G2", appCrashMatcher.id(),
2600 GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
2601 *config.add_gauge_metric() = gaugeMetric;
2602
2603 ConfigKey key(123, 987);
2604 uint64_t timeNs = 456;
2605 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
2606 sp<AlarmMonitor> anomalyAlarmMonitor;
2607 sp<AlarmMonitor> periodicAlarmMonitor;
2608 sp<UidMap> uidMap;
2609 sp<MetricsManager> metricsManager =
2610 new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
2611 anomalyAlarmMonitor, periodicAlarmMonitor);
2612 ASSERT_TRUE(metricsManager->isConfigValid());
2613 ASSERT_EQ(12, metricsManager->mAllMetricProducers.size());
2614
2615 sp<MetricProducer> uidCountMetricProducer = metricsManager->mAllMetricProducers[0];
2616 sp<MetricProducer> countMetricProducer = metricsManager->mAllMetricProducers[1];
2617 sp<MetricProducer> uidDurationMetricProducer = metricsManager->mAllMetricProducers[2];
2618 sp<MetricProducer> durationMetricProducer = metricsManager->mAllMetricProducers[3];
2619 sp<MetricProducer> uidEventMetricProducer = metricsManager->mAllMetricProducers[4];
2620 sp<MetricProducer> eventMetricProducer = metricsManager->mAllMetricProducers[5];
2621 sp<MetricProducer> uidValueMetricProducer = metricsManager->mAllMetricProducers[6];
2622 sp<MetricProducer> valueMetricProducer = metricsManager->mAllMetricProducers[7];
2623 sp<MetricProducer> uidKllMetricProducer = metricsManager->mAllMetricProducers[8];
2624 sp<MetricProducer> kllMetricProducer = metricsManager->mAllMetricProducers[9];
2625 sp<MetricProducer> uidGaugeMetricProducer = metricsManager->mAllMetricProducers[10];
2626 sp<MetricProducer> gaugeMetricProducer = metricsManager->mAllMetricProducers[11];
2627
2628 // Check uid what fields is set correctly or empty.
2629 EXPECT_EQ(1, uidCountMetricProducer->mUidFields.size());
2630 EXPECT_EQ(true, countMetricProducer->mUidFields.empty());
2631 EXPECT_EQ(1, uidDurationMetricProducer->mUidFields.size());
2632 EXPECT_EQ(true, durationMetricProducer->mUidFields.empty());
2633 EXPECT_EQ(1, uidEventMetricProducer->mUidFields.size());
2634 EXPECT_EQ(true, eventMetricProducer->mUidFields.empty());
2635 EXPECT_EQ(1, uidValueMetricProducer->mUidFields.size());
2636 EXPECT_EQ(true, valueMetricProducer->mUidFields.empty());
2637 EXPECT_EQ(1, uidKllMetricProducer->mUidFields.size());
2638 EXPECT_EQ(true, kllMetricProducer->mUidFields.empty());
2639 EXPECT_EQ(1, uidGaugeMetricProducer->mUidFields.size());
2640 EXPECT_EQ(true, gaugeMetricProducer->mUidFields.empty());
2641 }
2642
TEST_F(MetricsManagerUtilTest,TestMetricHasRepeatedUidField_PositionANY)2643 TEST_F(MetricsManagerUtilTest, TestMetricHasRepeatedUidField_PositionANY) {
2644 AtomMatcher testAtomReportedMatcher =
2645 CreateSimpleAtomMatcher("TEST_ATOM_REPORTED", util::TEST_ATOM_REPORTED);
2646
2647 StatsdConfig config;
2648 *config.add_atom_matcher() = testAtomReportedMatcher;
2649
2650 CountMetric metric = createCountMetric("CountSampledTestAtomReportedPerRepeatedIntField",
2651 testAtomReportedMatcher.id(), nullopt, {});
2652 *metric.mutable_uid_fields() = CreateRepeatedDimensions(
2653 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ANY});
2654 *config.add_count_metric() = metric;
2655
2656 EXPECT_EQ(initConfig(config),
2657 InvalidConfigReason(INVALID_CONFIG_REASON_UID_FIELDS_WITH_POSITION_ANY, metric.id()));
2658 }
2659
2660 } // namespace statsd
2661 } // namespace os
2662 } // namespace android
2663
2664 #else
2665 GTEST_LOG_(INFO) << "This test does nothing.\n";
2666 #endif
2667