Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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