• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gtest/gtest.h>
16 
17 #include "src/condition/ConditionTracker.h"
18 #include "src/matchers/LogMatchingTracker.h"
19 #include "src/metrics/CountMetricProducer.h"
20 #include "src/metrics/GaugeMetricProducer.h"
21 #include "src/metrics/MetricProducer.h"
22 #include "src/metrics/ValueMetricProducer.h"
23 #include "src/metrics/metrics_manager_util.h"
24 #include "statsd_test_util.h"
25 
26 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
27 
28 #include <stdio.h>
29 #include <set>
30 #include <unordered_map>
31 #include <vector>
32 
33 using namespace android::os::statsd;
34 using android::sp;
35 using std::set;
36 using std::unordered_map;
37 using std::vector;
38 using android::os::statsd::Predicate;
39 
40 #ifdef __ANDROID__
41 
42 // TODO: ADD MORE TEST CASES.
43 
44 const ConfigKey kConfigKey(0, 12345);
45 
46 const long timeBaseSec = 1000;
47 
buildGoodConfig()48 StatsdConfig buildGoodConfig() {
49     StatsdConfig config;
50     config.set_id(12345);
51 
52     AtomMatcher* eventMatcher = config.add_atom_matcher();
53     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
54 
55     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
56     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
57     simpleAtomMatcher->add_field_value_matcher()->set_field(
58             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
59     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
60             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
61 
62     eventMatcher = config.add_atom_matcher();
63     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
64 
65     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
66     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
67     simpleAtomMatcher->add_field_value_matcher()->set_field(
68             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
69     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
70             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
71 
72     eventMatcher = config.add_atom_matcher();
73     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
74 
75     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
76     combination->set_operation(LogicalOperation::OR);
77     combination->add_matcher(StringToId("SCREEN_IS_ON"));
78     combination->add_matcher(StringToId("SCREEN_IS_OFF"));
79 
80     CountMetric* metric = config.add_count_metric();
81     metric->set_id(3);
82     metric->set_what(StringToId("SCREEN_IS_ON"));
83     metric->set_bucket(ONE_MINUTE);
84     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
85     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
86 
87     config.add_no_report_metric(3);
88 
89     auto alert = config.add_alert();
90     alert->set_id(3);
91     alert->set_metric_id(3);
92     alert->set_num_buckets(10);
93     alert->set_refractory_period_secs(100);
94     alert->set_trigger_if_sum_gt(100);
95     return config;
96 }
97 
buildCircleMatchers()98 StatsdConfig buildCircleMatchers() {
99     StatsdConfig config;
100     config.set_id(12345);
101 
102     AtomMatcher* eventMatcher = config.add_atom_matcher();
103     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
104 
105     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
106     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
107     simpleAtomMatcher->add_field_value_matcher()->set_field(
108             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
109     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
110             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
111 
112     eventMatcher = config.add_atom_matcher();
113     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
114 
115     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
116     combination->set_operation(LogicalOperation::OR);
117     combination->add_matcher(StringToId("SCREEN_IS_ON"));
118     // Circle dependency
119     combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
120 
121     return config;
122 }
123 
buildAlertWithUnknownMetric()124 StatsdConfig buildAlertWithUnknownMetric() {
125     StatsdConfig config;
126     config.set_id(12345);
127 
128     AtomMatcher* eventMatcher = config.add_atom_matcher();
129     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
130 
131     CountMetric* metric = config.add_count_metric();
132     metric->set_id(3);
133     metric->set_what(StringToId("SCREEN_IS_ON"));
134     metric->set_bucket(ONE_MINUTE);
135     metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
136     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
137 
138     auto alert = config.add_alert();
139     alert->set_id(3);
140     alert->set_metric_id(2);
141     alert->set_num_buckets(10);
142     alert->set_refractory_period_secs(100);
143     alert->set_trigger_if_sum_gt(100);
144     return config;
145 }
146 
buildMissingMatchers()147 StatsdConfig buildMissingMatchers() {
148     StatsdConfig config;
149     config.set_id(12345);
150 
151     AtomMatcher* eventMatcher = config.add_atom_matcher();
152     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
153 
154     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
155     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
156     simpleAtomMatcher->add_field_value_matcher()->set_field(
157             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
158     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
159             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
160 
161     eventMatcher = config.add_atom_matcher();
162     eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
163 
164     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
165     combination->set_operation(LogicalOperation::OR);
166     combination->add_matcher(StringToId("SCREEN_IS_ON"));
167     // undefined matcher
168     combination->add_matcher(StringToId("ABC"));
169 
170     return config;
171 }
172 
buildMissingPredicate()173 StatsdConfig buildMissingPredicate() {
174     StatsdConfig config;
175     config.set_id(12345);
176 
177     CountMetric* metric = config.add_count_metric();
178     metric->set_id(3);
179     metric->set_what(StringToId("SCREEN_EVENT"));
180     metric->set_bucket(ONE_MINUTE);
181     metric->set_condition(StringToId("SOME_CONDITION"));
182 
183     AtomMatcher* eventMatcher = config.add_atom_matcher();
184     eventMatcher->set_id(StringToId("SCREEN_EVENT"));
185 
186     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
187     simpleAtomMatcher->set_atom_id(2);
188 
189     return config;
190 }
191 
buildDimensionMetricsWithMultiTags()192 StatsdConfig buildDimensionMetricsWithMultiTags() {
193     StatsdConfig config;
194     config.set_id(12345);
195 
196     AtomMatcher* eventMatcher = config.add_atom_matcher();
197     eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
198     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
199     simpleAtomMatcher->set_atom_id(2);
200 
201     eventMatcher = config.add_atom_matcher();
202     eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
203     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
204     simpleAtomMatcher->set_atom_id(3);
205 
206     eventMatcher = config.add_atom_matcher();
207     eventMatcher->set_id(StringToId("BATTERY_LOW"));
208 
209     AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
210     combination->set_operation(LogicalOperation::OR);
211     combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
212     combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
213 
214     // Count process state changes, slice by uid, while SCREEN_IS_OFF
215     CountMetric* metric = config.add_count_metric();
216     metric->set_id(3);
217     metric->set_what(StringToId("BATTERY_LOW"));
218     metric->set_bucket(ONE_MINUTE);
219     // This case is interesting. We want to dimension across two atoms.
220     metric->mutable_dimensions_in_what()->add_child()->set_field(1);
221 
222     auto alert = config.add_alert();
223     alert->set_id(103);
224     alert->set_metric_id(3);
225     alert->set_num_buckets(10);
226     alert->set_refractory_period_secs(100);
227     alert->set_trigger_if_sum_gt(100);
228     return config;
229 }
230 
buildCirclePredicates()231 StatsdConfig buildCirclePredicates() {
232     StatsdConfig config;
233     config.set_id(12345);
234 
235     AtomMatcher* eventMatcher = config.add_atom_matcher();
236     eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
237 
238     SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
239     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
240     simpleAtomMatcher->add_field_value_matcher()->set_field(
241             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
242     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
243             2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
244 
245     eventMatcher = config.add_atom_matcher();
246     eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
247 
248     simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
249     simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
250     simpleAtomMatcher->add_field_value_matcher()->set_field(
251             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
252     simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
253             1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
254 
255     auto condition = config.add_predicate();
256     condition->set_id(StringToId("SCREEN_IS_ON"));
257     SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
258     simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
259     simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
260 
261     condition = config.add_predicate();
262     condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
263 
264     Predicate_Combination* combination = condition->mutable_combination();
265     combination->set_operation(LogicalOperation::OR);
266     combination->add_predicate(StringToId("SCREEN_IS_ON"));
267     combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
268 
269     return config;
270 }
271 
TEST(MetricsManagerTest,TestGoodConfig)272 TEST(MetricsManagerTest, TestGoodConfig) {
273     UidMap uidMap;
274     sp<AlarmMonitor> anomalyAlarmMonitor;
275     sp<AlarmMonitor> periodicAlarmMonitor;
276     StatsdConfig config = buildGoodConfig();
277     set<int> allTagIds;
278     vector<sp<LogMatchingTracker>> allAtomMatchers;
279     vector<sp<ConditionTracker>> allConditionTrackers;
280     vector<sp<MetricProducer>> allMetricProducers;
281     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
282     std::vector<sp<AlarmTracker>> allAlarmTrackers;
283     unordered_map<int, std::vector<int>> conditionToMetricMap;
284     unordered_map<int, std::vector<int>> trackerToMetricMap;
285     unordered_map<int, std::vector<int>> trackerToConditionMap;
286     std::set<int64_t> noReportMetricIds;
287 
288     EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap,
289                                  anomalyAlarmMonitor, periodicAlarmMonitor,
290                                  timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
291                                  allConditionTrackers, allMetricProducers, allAnomalyTrackers,
292                                  allAlarmTrackers,
293                                  conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
294                                  noReportMetricIds));
295     EXPECT_EQ(1u, allMetricProducers.size());
296     EXPECT_EQ(1u, allAnomalyTrackers.size());
297     EXPECT_EQ(1u, noReportMetricIds.size());
298 }
299 
TEST(MetricsManagerTest,TestDimensionMetricsWithMultiTags)300 TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
301     UidMap uidMap;
302     sp<AlarmMonitor> anomalyAlarmMonitor;
303     sp<AlarmMonitor> periodicAlarmMonitor;
304     StatsdConfig config = buildDimensionMetricsWithMultiTags();
305     set<int> allTagIds;
306     vector<sp<LogMatchingTracker>> allAtomMatchers;
307     vector<sp<ConditionTracker>> allConditionTrackers;
308     vector<sp<MetricProducer>> allMetricProducers;
309     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
310     std::vector<sp<AlarmTracker>> allAlarmTrackers;
311     unordered_map<int, std::vector<int>> conditionToMetricMap;
312     unordered_map<int, std::vector<int>> trackerToMetricMap;
313     unordered_map<int, std::vector<int>> trackerToConditionMap;
314     std::set<int64_t> noReportMetricIds;
315 
316     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
317                                   anomalyAlarmMonitor, periodicAlarmMonitor,
318                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
319                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
320                                   allAlarmTrackers,
321                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
322                                   noReportMetricIds));
323 }
324 
TEST(MetricsManagerTest,TestCircleLogMatcherDependency)325 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
326     UidMap uidMap;
327     sp<AlarmMonitor> anomalyAlarmMonitor;
328     sp<AlarmMonitor> periodicAlarmMonitor;
329     StatsdConfig config = buildCircleMatchers();
330     set<int> allTagIds;
331     vector<sp<LogMatchingTracker>> allAtomMatchers;
332     vector<sp<ConditionTracker>> allConditionTrackers;
333     vector<sp<MetricProducer>> allMetricProducers;
334     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
335     std::vector<sp<AlarmTracker>> allAlarmTrackers;
336     unordered_map<int, std::vector<int>> conditionToMetricMap;
337     unordered_map<int, std::vector<int>> trackerToMetricMap;
338     unordered_map<int, std::vector<int>> trackerToConditionMap;
339     std::set<int64_t> noReportMetricIds;
340 
341     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
342                                   anomalyAlarmMonitor, periodicAlarmMonitor,
343                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
344                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
345                                   allAlarmTrackers,
346                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
347                                   noReportMetricIds));
348 }
349 
TEST(MetricsManagerTest,TestMissingMatchers)350 TEST(MetricsManagerTest, TestMissingMatchers) {
351     UidMap uidMap;
352     sp<AlarmMonitor> anomalyAlarmMonitor;
353     sp<AlarmMonitor> periodicAlarmMonitor;
354     StatsdConfig config = buildMissingMatchers();
355     set<int> allTagIds;
356     vector<sp<LogMatchingTracker>> allAtomMatchers;
357     vector<sp<ConditionTracker>> allConditionTrackers;
358     vector<sp<MetricProducer>> allMetricProducers;
359     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
360     std::vector<sp<AlarmTracker>> allAlarmTrackers;
361     unordered_map<int, std::vector<int>> conditionToMetricMap;
362     unordered_map<int, std::vector<int>> trackerToMetricMap;
363     unordered_map<int, std::vector<int>> trackerToConditionMap;
364     std::set<int64_t> noReportMetricIds;
365     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
366                                   anomalyAlarmMonitor, periodicAlarmMonitor,
367                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
368                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
369                                   allAlarmTrackers,
370                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
371                                   noReportMetricIds));
372 }
373 
TEST(MetricsManagerTest,TestMissingPredicate)374 TEST(MetricsManagerTest, TestMissingPredicate) {
375     UidMap uidMap;
376     sp<AlarmMonitor> anomalyAlarmMonitor;
377     sp<AlarmMonitor> periodicAlarmMonitor;
378     StatsdConfig config = buildMissingPredicate();
379     set<int> allTagIds;
380     vector<sp<LogMatchingTracker>> allAtomMatchers;
381     vector<sp<ConditionTracker>> allConditionTrackers;
382     vector<sp<MetricProducer>> allMetricProducers;
383     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
384     std::vector<sp<AlarmTracker>> allAlarmTrackers;
385     unordered_map<int, std::vector<int>> conditionToMetricMap;
386     unordered_map<int, std::vector<int>> trackerToMetricMap;
387     unordered_map<int, std::vector<int>> trackerToConditionMap;
388     std::set<int64_t> noReportMetricIds;
389     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
390                                   anomalyAlarmMonitor, periodicAlarmMonitor,
391                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
392                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
393                                   allAlarmTrackers,
394                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
395                                   noReportMetricIds));
396 }
397 
TEST(MetricsManagerTest,TestCirclePredicateDependency)398 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
399     UidMap uidMap;
400     sp<AlarmMonitor> anomalyAlarmMonitor;
401     sp<AlarmMonitor> periodicAlarmMonitor;
402     StatsdConfig config = buildCirclePredicates();
403     set<int> allTagIds;
404     vector<sp<LogMatchingTracker>> allAtomMatchers;
405     vector<sp<ConditionTracker>> allConditionTrackers;
406     vector<sp<MetricProducer>> allMetricProducers;
407     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
408     std::vector<sp<AlarmTracker>> allAlarmTrackers;
409     unordered_map<int, std::vector<int>> conditionToMetricMap;
410     unordered_map<int, std::vector<int>> trackerToMetricMap;
411     unordered_map<int, std::vector<int>> trackerToConditionMap;
412     std::set<int64_t> noReportMetricIds;
413 
414     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
415                                   anomalyAlarmMonitor, periodicAlarmMonitor,
416                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
417                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
418                                   allAlarmTrackers,
419                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
420                                   noReportMetricIds));
421 }
422 
TEST(MetricsManagerTest,testAlertWithUnknownMetric)423 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
424     UidMap uidMap;
425     sp<AlarmMonitor> anomalyAlarmMonitor;
426     sp<AlarmMonitor> periodicAlarmMonitor;
427     StatsdConfig config = buildAlertWithUnknownMetric();
428     set<int> allTagIds;
429     vector<sp<LogMatchingTracker>> allAtomMatchers;
430     vector<sp<ConditionTracker>> allConditionTrackers;
431     vector<sp<MetricProducer>> allMetricProducers;
432     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
433     std::vector<sp<AlarmTracker>> allAlarmTrackers;
434     unordered_map<int, std::vector<int>> conditionToMetricMap;
435     unordered_map<int, std::vector<int>> trackerToMetricMap;
436     unordered_map<int, std::vector<int>> trackerToConditionMap;
437     std::set<int64_t> noReportMetricIds;
438 
439     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
440                                   anomalyAlarmMonitor, periodicAlarmMonitor,
441                                   timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
442                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
443                                   allAlarmTrackers,
444                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
445                                   noReportMetricIds));
446 }
447 
448 #else
449 GTEST_LOG_(INFO) << "This test does nothing.\n";
450 #endif
451