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