Home | History | Annotate | Download | only in e2e
      1 // Copyright (C) 2019 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/StatsLogProcessor.h"
     18 #include "src/stats_log_util.h"
     19 #include "tests/statsd_test_util.h"
     20 
     21 #include <vector>
     22 
     23 namespace android {
     24 namespace os {
     25 namespace statsd {
     26 
     27 #ifdef __ANDROID__
     28 
     29 TEST(DurationMetricE2eTest, TestOneBucket) {
     30     StatsdConfig config;
     31     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
     32 
     33     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
     34     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
     35     *config.add_atom_matcher() = screenOnMatcher;
     36     *config.add_atom_matcher() = screenOffMatcher;
     37 
     38     auto durationPredicate = CreateScreenIsOnPredicate();
     39     *config.add_predicate() = durationPredicate;
     40 
     41     int64_t metricId = 123456;
     42     auto durationMetric = config.add_duration_metric();
     43     durationMetric->set_id(metricId);
     44     durationMetric->set_what(durationPredicate.id());
     45     durationMetric->set_bucket(FIVE_MINUTES);
     46     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
     47 
     48 
     49     const int64_t baseTimeNs = 0; // 0:00
     50     const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
     51     const int64_t bucketSizeNs =
     52             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
     53 
     54     int uid = 12345;
     55     int64_t cfgId = 98765;
     56     ConfigKey cfgKey(uid, cfgId);
     57 
     58     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
     59 
     60     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     61     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     62     EXPECT_TRUE(metricsManager->isConfigValid());
     63     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     64     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     65     EXPECT_TRUE(metricsManager->isActive());
     66     EXPECT_TRUE(metricProducer->mIsActive);
     67 
     68     std::unique_ptr<LogEvent> event;
     69 
     70     // Screen is off at start of bucket.
     71     event = CreateScreenStateChangedEvent(
     72             android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
     73     processor->OnLogEvent(event.get());
     74 
     75     // Turn screen on.
     76     const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
     77     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
     78     processor->OnLogEvent(event.get());
     79 
     80     // Turn off screen 30 seconds after turning on.
     81     const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
     82     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
     83     processor->OnLogEvent(event.get());
     84 
     85     event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
     86     processor->OnLogEvent(event.get());
     87 
     88     ConfigMetricsReportList reports;
     89     vector<uint8_t> buffer;
     90     processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
     91                             ADB_DUMP, FAST, &buffer); // 5:01
     92     EXPECT_TRUE(buffer.size() > 0);
     93     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     94     backfillDimensionPath(&reports);
     95     backfillStartEndTimestamp(&reports);
     96     EXPECT_EQ(1, reports.reports_size());
     97     EXPECT_EQ(1, reports.reports(0).metrics_size());
     98     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     99     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
    100 
    101     const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
    102             reports.reports(0).metrics(0).duration_metrics();
    103     EXPECT_EQ(1, durationMetrics.data_size());
    104 
    105     auto data = durationMetrics.data(0);
    106     EXPECT_EQ(1, data.bucket_info_size());
    107     EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
    108     EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
    109     EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
    110 }
    111 
    112 TEST(DurationMetricE2eTest, TestTwoBuckets) {
    113     StatsdConfig config;
    114     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
    115 
    116     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    117     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
    118     *config.add_atom_matcher() = screenOnMatcher;
    119     *config.add_atom_matcher() = screenOffMatcher;
    120 
    121     auto durationPredicate = CreateScreenIsOnPredicate();
    122     *config.add_predicate() = durationPredicate;
    123 
    124     int64_t metricId = 123456;
    125     auto durationMetric = config.add_duration_metric();
    126     durationMetric->set_id(metricId);
    127     durationMetric->set_what(durationPredicate.id());
    128     durationMetric->set_bucket(FIVE_MINUTES);
    129     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
    130 
    131 
    132     const int64_t baseTimeNs = 0; // 0:00
    133     const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
    134     const int64_t bucketSizeNs =
    135             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
    136 
    137     int uid = 12345;
    138     int64_t cfgId = 98765;
    139     ConfigKey cfgKey(uid, cfgId);
    140 
    141     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
    142 
    143     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    144     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
    145     EXPECT_TRUE(metricsManager->isConfigValid());
    146     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
    147     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
    148     EXPECT_TRUE(metricsManager->isActive());
    149     EXPECT_TRUE(metricProducer->mIsActive);
    150 
    151     std::unique_ptr<LogEvent> event;
    152 
    153     // Screen is off at start of bucket.
    154     event = CreateScreenStateChangedEvent(
    155             android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
    156     processor->OnLogEvent(event.get());
    157 
    158     // Turn screen on.
    159     const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
    160     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
    161     processor->OnLogEvent(event.get());
    162 
    163     // Turn off screen 30 seconds after turning on.
    164     const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
    165     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
    166     processor->OnLogEvent(event.get());
    167 
    168     event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
    169     processor->OnLogEvent(event.get());
    170 
    171     ConfigMetricsReportList reports;
    172     vector<uint8_t> buffer;
    173     processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false, true,
    174                             ADB_DUMP, FAST, &buffer); // 10:01
    175     EXPECT_TRUE(buffer.size() > 0);
    176     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    177     backfillDimensionPath(&reports);
    178     backfillStartEndTimestamp(&reports);
    179     EXPECT_EQ(1, reports.reports_size());
    180     EXPECT_EQ(1, reports.reports(0).metrics_size());
    181     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
    182     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
    183 
    184     const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
    185             reports.reports(0).metrics(0).duration_metrics();
    186     EXPECT_EQ(1, durationMetrics.data_size());
    187 
    188     auto data = durationMetrics.data(0);
    189     EXPECT_EQ(1, data.bucket_info_size());
    190 
    191     auto bucketInfo = data.bucket_info(0);
    192     EXPECT_EQ(0, bucketInfo.bucket_num());
    193     EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
    194     EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
    195     EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
    196 }
    197 
    198 TEST(DurationMetricE2eTest, TestWithActivation) {
    199     StatsdConfig config;
    200     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
    201 
    202     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    203     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
    204     auto crashMatcher = CreateProcessCrashAtomMatcher();
    205     *config.add_atom_matcher() = screenOnMatcher;
    206     *config.add_atom_matcher() = screenOffMatcher;
    207     *config.add_atom_matcher() = crashMatcher;
    208 
    209     auto durationPredicate = CreateScreenIsOnPredicate();
    210     *config.add_predicate() = durationPredicate;
    211 
    212     int64_t metricId = 123456;
    213     auto durationMetric = config.add_duration_metric();
    214     durationMetric->set_id(metricId);
    215     durationMetric->set_what(durationPredicate.id());
    216     durationMetric->set_bucket(FIVE_MINUTES);
    217     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
    218 
    219     auto metric_activation1 = config.add_metric_activation();
    220     metric_activation1->set_metric_id(metricId);
    221     auto event_activation1 = metric_activation1->add_event_activation();
    222     event_activation1->set_atom_matcher_id(crashMatcher.id());
    223     event_activation1->set_ttl_seconds(30); // 30 secs.
    224 
    225     const int64_t bucketStartTimeNs = 10000000000;
    226     const int64_t bucketSizeNs =
    227             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
    228 
    229     int uid = 12345;
    230     int64_t cfgId = 98765;
    231     ConfigKey cfgKey(uid, cfgId);
    232 
    233     sp<UidMap> m = new UidMap();
    234     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
    235     sp<AlarmMonitor> anomalyAlarmMonitor;
    236     sp<AlarmMonitor> subscriberAlarmMonitor;
    237     vector<int64_t> activeConfigsBroadcast;
    238 
    239     int broadcastCount = 0;
    240     StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
    241             bucketStartTimeNs, [](const ConfigKey& key) { return true; },
    242             [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
    243                     const vector<int64_t>& activeConfigs) {
    244                 broadcastCount++;
    245                 EXPECT_EQ(broadcastUid, uid);
    246                 activeConfigsBroadcast.clear();
    247                 activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
    248                         activeConfigs.begin(), activeConfigs.end());
    249                 return true;
    250             });
    251 
    252     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config); // 0:00
    253 
    254     EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
    255     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
    256     EXPECT_TRUE(metricsManager->isConfigValid());
    257     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
    258     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
    259     auto& eventActivationMap = metricProducer->mEventActivationMap;
    260 
    261     EXPECT_FALSE(metricsManager->isActive());
    262     EXPECT_FALSE(metricProducer->mIsActive);
    263     EXPECT_EQ(eventActivationMap.size(), 1u);
    264     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
    265     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
    266     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
    267     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    268 
    269     std::unique_ptr<LogEvent> event;
    270 
    271     // Turn screen off.
    272     event = CreateScreenStateChangedEvent(
    273             android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 2 * NS_PER_SEC); // 0:02
    274     processor.OnLogEvent(event.get());
    275 
    276     // Turn screen on.
    277     const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:05
    278     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
    279     processor.OnLogEvent(event.get());
    280 
    281     // Activate metric.
    282     const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:10
    283     const int64_t activationEndNs =
    284             activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 0:40
    285     event = CreateAppCrashEvent(111, activationStartNs);
    286     processor.OnLogEvent(event.get());
    287     EXPECT_TRUE(metricsManager->isActive());
    288     EXPECT_TRUE(metricProducer->mIsActive);
    289     EXPECT_EQ(broadcastCount, 1);
    290     EXPECT_EQ(activeConfigsBroadcast.size(), 1);
    291     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
    292     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
    293     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
    294     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    295 
    296     // Expire activation.
    297     const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
    298     event = CreateScreenBrightnessChangedEvent(64, expirationNs); // 0:47
    299     processor.OnLogEvent(event.get());
    300     EXPECT_FALSE(metricsManager->isActive());
    301     EXPECT_FALSE(metricProducer->mIsActive);
    302     EXPECT_EQ(broadcastCount, 2);
    303     EXPECT_EQ(activeConfigsBroadcast.size(), 0);
    304     EXPECT_EQ(eventActivationMap.size(), 1u);
    305     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
    306     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
    307     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
    308     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    309 
    310     // Turn off screen 10 seconds after activation expiration.
    311     const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC; // 0:50
    312     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
    313     processor.OnLogEvent(event.get());
    314 
    315     // Turn screen on.
    316     const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC; // 0:55
    317     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
    318     processor.OnLogEvent(event.get());
    319 
    320     // Turn off screen.
    321     const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC; // 1:05
    322     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, duration2EndNs);
    323     processor.OnLogEvent(event.get());
    324 
    325     // Activate metric.
    326     const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC; // 1:10
    327     const int64_t activation2EndNs =
    328             activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 1:40
    329     event = CreateAppCrashEvent(211, activation2StartNs);
    330     processor.OnLogEvent(event.get());
    331     EXPECT_TRUE(metricsManager->isActive());
    332     EXPECT_TRUE(metricProducer->mIsActive);
    333     EXPECT_EQ(broadcastCount, 3);
    334     EXPECT_EQ(activeConfigsBroadcast.size(), 1);
    335     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
    336     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
    337     EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
    338     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    339 
    340     ConfigMetricsReportList reports;
    341     vector<uint8_t> buffer;
    342     processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
    343                             ADB_DUMP, FAST, &buffer); // 5:01
    344     EXPECT_TRUE(buffer.size() > 0);
    345     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    346     backfillDimensionPath(&reports);
    347     backfillStartEndTimestamp(&reports);
    348     EXPECT_EQ(1, reports.reports_size());
    349     EXPECT_EQ(1, reports.reports(0).metrics_size());
    350     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
    351     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
    352 
    353     const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
    354             reports.reports(0).metrics(0).duration_metrics();
    355     EXPECT_EQ(1, durationMetrics.data_size());
    356 
    357     auto data = durationMetrics.data(0);
    358     EXPECT_EQ(1, data.bucket_info_size());
    359 
    360     auto bucketInfo = data.bucket_info(0);
    361     EXPECT_EQ(0, bucketInfo.bucket_num());
    362     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
    363     EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
    364     EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
    365 }
    366 
    367 TEST(DurationMetricE2eTest, TestWithCondition) {
    368     StatsdConfig config;
    369     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
    370     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
    371     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
    372     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
    373     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
    374 
    375     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
    376     *config.add_predicate() = holdingWakelockPredicate;
    377 
    378     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
    379     *config.add_predicate() = isInBackgroundPredicate;
    380 
    381     auto durationMetric = config.add_duration_metric();
    382     durationMetric->set_id(StringToId("WakelockDuration"));
    383     durationMetric->set_what(holdingWakelockPredicate.id());
    384     durationMetric->set_condition(isInBackgroundPredicate.id());
    385     durationMetric->set_aggregation_type(DurationMetric::SUM);
    386     durationMetric->set_bucket(FIVE_MINUTES);
    387 
    388     ConfigKey cfgKey;
    389     uint64_t bucketStartTimeNs = 10000000000;
    390     uint64_t bucketSizeNs =
    391             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    392     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    393     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    394     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
    395     EXPECT_TRUE(metricsManager->isConfigValid());
    396     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
    397     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
    398     auto& eventActivationMap = metricProducer->mEventActivationMap;
    399     EXPECT_TRUE(metricsManager->isActive());
    400     EXPECT_TRUE(metricProducer->mIsActive);
    401     EXPECT_TRUE(eventActivationMap.empty());
    402 
    403     int appUid = 123;
    404     std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
    405 
    406     auto event = CreateAcquireWakelockEvent(
    407             attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
    408     processor->OnLogEvent(event.get());
    409 
    410     event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
    411     processor->OnLogEvent(event.get());
    412 
    413     event = CreateMoveToForegroundEvent(
    414             appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
    415     processor->OnLogEvent(event.get());
    416 
    417     event = CreateReleaseWakelockEvent(
    418             attributions1, "wl1", bucketStartTimeNs + 4 * 60 * NS_PER_SEC); // 4:00
    419     processor->OnLogEvent(event.get());
    420 
    421     vector<uint8_t> buffer;
    422     ConfigMetricsReportList reports;
    423     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
    424                             ADB_DUMP, FAST, &buffer);
    425     EXPECT_GT(buffer.size(), 0);
    426     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    427     backfillDimensionPath(&reports);
    428     backfillStringInReport(&reports);
    429     backfillStartEndTimestamp(&reports);
    430 
    431     EXPECT_EQ(1, reports.reports_size());
    432     EXPECT_EQ(1, reports.reports(0).metrics_size());
    433     EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
    434 
    435     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    436 
    437     // Validate bucket info.
    438     EXPECT_EQ(1, data.bucket_info_size());
    439 
    440     auto bucketInfo = data.bucket_info(0);
    441     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
    442     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
    443     EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
    444 }
    445 
    446 TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
    447     StatsdConfig config;
    448     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
    449     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    450     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
    451     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
    452     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
    453     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
    454 
    455     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
    456     // The predicate is dimensioning by first attribution node by uid.
    457     FieldMatcher dimensions = CreateAttributionUidDimensions(
    458             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    459     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
    460     *config.add_predicate() = holdingWakelockPredicate;
    461 
    462     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
    463     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
    464         CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
    465     *config.add_predicate() = isInBackgroundPredicate;
    466 
    467     auto durationMetric = config.add_duration_metric();
    468     durationMetric->set_id(StringToId("WakelockDuration"));
    469     durationMetric->set_what(holdingWakelockPredicate.id());
    470     durationMetric->set_condition(isInBackgroundPredicate.id());
    471     durationMetric->set_aggregation_type(DurationMetric::SUM);
    472     // The metric is dimensioning by first attribution node and only by uid.
    473     *durationMetric->mutable_dimensions_in_what() =
    474         CreateAttributionUidDimensions(
    475             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    476     durationMetric->set_bucket(FIVE_MINUTES);
    477 
    478     // Links between wakelock state atom and condition of app is in background.
    479     auto links = durationMetric->add_links();
    480     links->set_condition(isInBackgroundPredicate.id());
    481     auto dimensionWhat = links->mutable_fields_in_what();
    482     dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
    483     dimensionWhat->add_child()->set_field(1);  // uid field.
    484     *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
    485             android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
    486 
    487     ConfigKey cfgKey;
    488     uint64_t bucketStartTimeNs = 10000000000;
    489     uint64_t bucketSizeNs =
    490             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    491     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    492     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    493     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
    494     EXPECT_TRUE(metricsManager->isConfigValid());
    495     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
    496     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
    497     auto& eventActivationMap = metricProducer->mEventActivationMap;
    498     EXPECT_TRUE(metricsManager->isActive());
    499     EXPECT_TRUE(metricProducer->mIsActive);
    500     EXPECT_TRUE(eventActivationMap.empty());
    501 
    502     int appUid = 123;
    503     std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
    504 
    505     auto event = CreateAcquireWakelockEvent(
    506             attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
    507     processor->OnLogEvent(event.get());
    508 
    509     event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
    510     processor->OnLogEvent(event.get());
    511 
    512     event = CreateReleaseWakelockEvent(
    513             attributions1, "wl1", bucketStartTimeNs + 60 * NS_PER_SEC); // 1:00
    514     processor->OnLogEvent(event.get());
    515 
    516 
    517     event = CreateMoveToForegroundEvent(
    518             appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
    519     processor->OnLogEvent(event.get());
    520 
    521     vector<uint8_t> buffer;
    522     ConfigMetricsReportList reports;
    523     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
    524                             ADB_DUMP, FAST, &buffer);
    525     EXPECT_GT(buffer.size(), 0);
    526     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    527     backfillDimensionPath(&reports);
    528     backfillStringInReport(&reports);
    529     backfillStartEndTimestamp(&reports);
    530 
    531     EXPECT_EQ(1, reports.reports_size());
    532     EXPECT_EQ(1, reports.reports(0).metrics_size());
    533     EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
    534 
    535     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    536     // Validate dimension value.
    537     ValidateAttributionUidDimension(data.dimensions_in_what(),
    538                                     android::util::WAKELOCK_STATE_CHANGED, appUid);
    539     // Validate bucket info.
    540     EXPECT_EQ(1, data.bucket_info_size());
    541 
    542     auto bucketInfo = data.bucket_info(0);
    543     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
    544     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
    545     EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
    546 }
    547 
    548 TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
    549     StatsdConfig config;
    550     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
    551     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    552     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
    553     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
    554     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
    555     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
    556     *config.add_atom_matcher() = screenOnMatcher;
    557 
    558     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
    559     // The predicate is dimensioning by first attribution node by uid.
    560     FieldMatcher dimensions = CreateAttributionUidDimensions(
    561             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    562     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
    563     *config.add_predicate() = holdingWakelockPredicate;
    564 
    565     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
    566     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
    567         CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
    568     *config.add_predicate() = isInBackgroundPredicate;
    569 
    570     auto durationMetric = config.add_duration_metric();
    571     durationMetric->set_id(StringToId("WakelockDuration"));
    572     durationMetric->set_what(holdingWakelockPredicate.id());
    573     durationMetric->set_condition(isInBackgroundPredicate.id());
    574     durationMetric->set_aggregation_type(DurationMetric::SUM);
    575     // The metric is dimensioning by first attribution node and only by uid.
    576     *durationMetric->mutable_dimensions_in_what() =
    577         CreateAttributionUidDimensions(
    578             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    579     durationMetric->set_bucket(FIVE_MINUTES);
    580 
    581     // Links between wakelock state atom and condition of app is in background.
    582     auto links = durationMetric->add_links();
    583     links->set_condition(isInBackgroundPredicate.id());
    584     auto dimensionWhat = links->mutable_fields_in_what();
    585     dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
    586     dimensionWhat->add_child()->set_field(1);  // uid field.
    587     *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
    588             android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
    589 
    590     auto metric_activation1 = config.add_metric_activation();
    591     metric_activation1->set_metric_id(durationMetric->id());
    592     auto event_activation1 = metric_activation1->add_event_activation();
    593     event_activation1->set_atom_matcher_id(screenOnMatcher.id());
    594     event_activation1->set_ttl_seconds(60 * 2);  // 2 minutes.
    595 
    596     ConfigKey cfgKey;
    597     uint64_t bucketStartTimeNs = 10000000000;
    598     uint64_t bucketSizeNs =
    599             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    600     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    601     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    602     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
    603     EXPECT_TRUE(metricsManager->isConfigValid());
    604     EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
    605     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
    606     auto& eventActivationMap = metricProducer->mEventActivationMap;
    607     EXPECT_FALSE(metricsManager->isActive());
    608     EXPECT_FALSE(metricProducer->mIsActive);
    609     EXPECT_EQ(eventActivationMap.size(), 1u);
    610     EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
    611     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
    612     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
    613     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    614 
    615     int appUid = 123;
    616     std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
    617 
    618     auto event = CreateAcquireWakelockEvent(
    619             attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
    620     processor->OnLogEvent(event.get());
    621     EXPECT_FALSE(metricsManager->isActive());
    622     EXPECT_FALSE(metricProducer->mIsActive);
    623     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
    624     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
    625     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    626 
    627     event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
    628     processor->OnLogEvent(event.get());
    629     EXPECT_FALSE(metricsManager->isActive());
    630     EXPECT_FALSE(metricProducer->mIsActive);
    631     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
    632     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
    633     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    634 
    635     const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC; // 0:30
    636     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
    637     processor->OnLogEvent(event.get());
    638     EXPECT_TRUE(metricsManager->isActive());
    639     EXPECT_TRUE(metricProducer->mIsActive);
    640     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
    641     EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
    642     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    643 
    644     const int64_t durationEndNs =
    645             durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC; // 3:00
    646     event = CreateAppCrashEvent(333, durationEndNs);
    647     processor->OnLogEvent(event.get());
    648     EXPECT_FALSE(metricsManager->isActive());
    649     EXPECT_FALSE(metricProducer->mIsActive);
    650     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
    651     EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
    652     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    653 
    654     event = CreateMoveToForegroundEvent(
    655             appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
    656     processor->OnLogEvent(event.get());
    657 
    658     event = CreateReleaseWakelockEvent(
    659             attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC); // 4:17
    660     processor->OnLogEvent(event.get());
    661 
    662     event = CreateMoveToBackgroundEvent(
    663             appUid, bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC); // 4:20
    664     processor->OnLogEvent(event.get());
    665 
    666     event = CreateAcquireWakelockEvent(
    667             attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC); // 4:25
    668     processor->OnLogEvent(event.get());
    669 
    670     const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC; // 4:30
    671     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
    672     processor->OnLogEvent(event.get());
    673     EXPECT_TRUE(metricsManager->isActive());
    674     EXPECT_TRUE(metricProducer->mIsActive);
    675     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
    676     EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
    677     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
    678 
    679     vector<uint8_t> buffer;
    680     ConfigMetricsReportList reports;
    681     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
    682                             ADB_DUMP, FAST, &buffer);
    683     EXPECT_GT(buffer.size(), 0);
    684     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    685     backfillDimensionPath(&reports);
    686     backfillStringInReport(&reports);
    687     backfillStartEndTimestamp(&reports);
    688 
    689     EXPECT_EQ(1, reports.reports_size());
    690     EXPECT_EQ(1, reports.reports(0).metrics_size());
    691     EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
    692 
    693     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    694     // Validate dimension value.
    695     ValidateAttributionUidDimension(data.dimensions_in_what(),
    696                                     android::util::WAKELOCK_STATE_CHANGED, appUid);
    697     // Validate bucket info.
    698     EXPECT_EQ(2, data.bucket_info_size());
    699 
    700     auto bucketInfo = data.bucket_info(0);
    701     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
    702     EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
    703     EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
    704 
    705     bucketInfo = data.bucket_info(1);
    706     EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
    707     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
    708     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
    709 }
    710 
    711 #else
    712 GTEST_LOG_(INFO) << "This test does nothing.\n";
    713 #endif
    714 
    715 }  // namespace statsd
    716 }  // namespace os
    717 }  // namespace android
    718