Home | History | Annotate | Download | only in e2e
      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/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 namespace {
     30 
     31 StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
     32     StatsdConfig config;
     33     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
     34     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
     35     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
     36     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
     37     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
     38 
     39     auto screenIsOffPredicate = CreateScreenIsOffPredicate();
     40     *config.add_predicate() = screenIsOffPredicate;
     41 
     42     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
     43     // The predicate is dimensioning by any attribution node and both by uid and tag.
     44     FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
     45             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
     46     // Also slice by the wakelock tag
     47     dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
     48     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
     49     *config.add_predicate() = holdingWakelockPredicate;
     50 
     51     auto durationMetric = config.add_duration_metric();
     52     durationMetric->set_id(StringToId("WakelockDuration"));
     53     durationMetric->set_what(holdingWakelockPredicate.id());
     54     durationMetric->set_condition(screenIsOffPredicate.id());
     55     durationMetric->set_aggregation_type(aggregationType);
     56     // The metric is dimensioning by first attribution node and only by uid.
     57     *durationMetric->mutable_dimensions_in_what() =
     58         CreateAttributionUidDimensions(
     59             android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     60     durationMetric->set_bucket(FIVE_MINUTES);
     61     return config;
     62 }
     63 
     64 std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
     65                                                       CreateAttribution(222, "GMSCoreModule1"),
     66                                                       CreateAttribution(222, "GMSCoreModule2")};
     67 
     68 std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
     69                                                       CreateAttribution(222, "GMSCoreModule1"),
     70                                                       CreateAttribution(222, "GMSCoreModule2")};
     71 
     72 /*
     73 Events:
     74 Screen off is met from (200ns,1 min+500ns].
     75 Acquire event for wl1 from 2ns to 1min+2ns
     76 Acquire event for wl2 from 1min-10ns to 2min-15ns
     77 */
     78 void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
     79     uint64_t bucketStartTimeNs = 10000000000;
     80     uint64_t bucketSizeNs =
     81             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     82 
     83     auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
     84             android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 1);
     85     auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
     86             android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
     87     auto screenTurnedOnEvent2 =
     88             CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
     89                                           bucketStartTimeNs + bucketSizeNs + 500);
     90 
     91     auto acquireEvent1 = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
     92     auto releaseEvent1 =
     93             CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 2);
     94     auto acquireEvent2 =
     95             CreateAcquireWakelockEvent(attributions2, "wl2", bucketStartTimeNs + bucketSizeNs - 10);
     96     auto releaseEvent2 = CreateReleaseWakelockEvent(attributions2, "wl2",
     97                                                     bucketStartTimeNs + 2 * bucketSizeNs - 15);
     98 
     99     std::vector<std::unique_ptr<LogEvent>> events;
    100 
    101     events.push_back(std::move(screenTurnedOnEvent));
    102     events.push_back(std::move(screenTurnedOffEvent));
    103     events.push_back(std::move(screenTurnedOnEvent2));
    104     events.push_back(std::move(acquireEvent1));
    105     events.push_back(std::move(acquireEvent2));
    106     events.push_back(std::move(releaseEvent1));
    107     events.push_back(std::move(releaseEvent2));
    108 
    109     sortLogEventsByTimestamp(&events);
    110 
    111     for (const auto& event : events) {
    112         processor->OnLogEvent(event.get());
    113     }
    114 }
    115 
    116 }  // namespace
    117 
    118 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
    119     ConfigKey cfgKey;
    120     auto config = CreateStatsdConfig(DurationMetric::SUM);
    121     uint64_t bucketStartTimeNs = 10000000000;
    122     uint64_t bucketSizeNs =
    123             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    124     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    125     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    126     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    127     FeedEvents(config, processor);
    128     vector<uint8_t> buffer;
    129     ConfigMetricsReportList reports;
    130     processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
    131                             &buffer);
    132     EXPECT_TRUE(buffer.size() > 0);
    133     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    134     backfillDimensionPath(&reports);
    135     backfillStringInReport(&reports);
    136     backfillStartEndTimestamp(&reports);
    137 
    138     EXPECT_EQ(reports.reports_size(), 1);
    139     EXPECT_EQ(reports.reports(0).metrics_size(), 1);
    140     // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
    141     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
    142 
    143     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    144     // Validate dimension value.
    145     ValidateAttributionUidDimension(data.dimensions_in_what(),
    146                                     android::util::WAKELOCK_STATE_CHANGED, 111);
    147     // Validate bucket info.
    148     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
    149     data = reports.reports(0).metrics(0).duration_metrics().data(0);
    150     // The wakelock holding interval starts from the screen off event and to the end of the 1st
    151     // bucket.
    152     EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
    153 }
    154 
    155 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
    156     ConfigKey cfgKey;
    157     auto config = CreateStatsdConfig(DurationMetric::SUM);
    158     uint64_t bucketStartTimeNs = 10000000000;
    159     uint64_t bucketSizeNs =
    160             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    161     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    162     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    163     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    164     FeedEvents(config, processor);
    165     vector<uint8_t> buffer;
    166     ConfigMetricsReportList reports;
    167     processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
    168                             &buffer);
    169     EXPECT_TRUE(buffer.size() > 0);
    170     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    171     backfillDimensionPath(&reports);
    172     backfillStringInReport(&reports);
    173     backfillStartEndTimestamp(&reports);
    174     EXPECT_EQ(reports.reports_size(), 1);
    175     EXPECT_EQ(reports.reports(0).metrics_size(), 1);
    176     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
    177     // Dump the report after the end of 2nd bucket.
    178     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
    179     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    180     // Validate dimension value.
    181     ValidateAttributionUidDimension(data.dimensions_in_what(),
    182                                     android::util::WAKELOCK_STATE_CHANGED, 111);
    183     // Two output buckets.
    184     // The wakelock holding interval in the 1st bucket starts from the screen off event and to
    185     // the end of the 1st bucket.
    186     EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
    187               bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
    188     // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
    189     // ends at the second screen on event.
    190     EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
    191 }
    192 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
    193     ConfigKey cfgKey;
    194     auto config = CreateStatsdConfig(DurationMetric::SUM);
    195     uint64_t bucketStartTimeNs = 10000000000;
    196     uint64_t bucketSizeNs =
    197             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    198     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    199     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    200     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    201     FeedEvents(config, processor);
    202     vector<uint8_t> buffer;
    203     ConfigMetricsReportList reports;
    204 
    205     std::vector<std::unique_ptr<LogEvent>> events;
    206     events.push_back(
    207             CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
    208                                           bucketStartTimeNs + 2 * bucketSizeNs + 90));
    209     events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
    210                                                 bucketStartTimeNs + 2 * bucketSizeNs + 100));
    211     events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
    212                                                 bucketStartTimeNs + 5 * bucketSizeNs + 100));
    213     sortLogEventsByTimestamp(&events);
    214     for (const auto& event : events) {
    215         processor->OnLogEvent(event.get());
    216     }
    217 
    218     processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
    219                             &buffer);
    220     EXPECT_TRUE(buffer.size() > 0);
    221     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    222     backfillDimensionPath(&reports);
    223     backfillStringInReport(&reports);
    224     backfillStartEndTimestamp(&reports);
    225     EXPECT_EQ(reports.reports_size(), 1);
    226     EXPECT_EQ(reports.reports(0).metrics_size(), 1);
    227     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
    228     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
    229     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    230     ValidateAttributionUidDimension(data.dimensions_in_what(),
    231                                     android::util::WAKELOCK_STATE_CHANGED, 111);
    232     // The last wakelock holding spans 4 buckets.
    233     EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
    234     EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
    235     EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
    236     EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
    237 }
    238 
    239 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
    240     ConfigKey cfgKey;
    241     auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
    242     uint64_t bucketStartTimeNs = 10000000000;
    243     uint64_t bucketSizeNs =
    244             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    245     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    246     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    247     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    248     FeedEvents(config, processor);
    249     ConfigMetricsReportList reports;
    250     vector<uint8_t> buffer;
    251     processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
    252                             &buffer);
    253     EXPECT_TRUE(buffer.size() > 0);
    254 
    255     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    256     backfillDimensionPath(&reports);
    257     backfillStringInReport(&reports);
    258     backfillStartEndTimestamp(&reports);
    259 
    260     EXPECT_EQ(reports.reports_size(), 1);
    261 
    262     // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
    263     // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
    264     // itself.
    265     EXPECT_EQ(0, reports.reports(0).metrics_size());
    266 }
    267 
    268 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
    269     ConfigKey cfgKey;
    270     auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
    271     uint64_t bucketStartTimeNs = 10000000000;
    272     uint64_t bucketSizeNs =
    273             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    274     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    275     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    276     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    277     FeedEvents(config, processor);
    278     ConfigMetricsReportList reports;
    279     vector<uint8_t> buffer;
    280     processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
    281                             &buffer);
    282     EXPECT_TRUE(buffer.size() > 0);
    283     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    284     backfillDimensionPath(&reports);
    285     backfillStringInReport(&reports);
    286     backfillStartEndTimestamp(&reports);
    287     EXPECT_EQ(reports.reports_size(), 1);
    288     EXPECT_EQ(reports.reports(0).metrics_size(), 1);
    289     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
    290     // Dump the report after the end of 2nd bucket. One dimension with one bucket.
    291     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
    292     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    293     // Validate dimension value.
    294     ValidateAttributionUidDimension(data.dimensions_in_what(),
    295                                     android::util::WAKELOCK_STATE_CHANGED, 111);
    296     // The max is acquire event for wl1 to screen off start.
    297     EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
    298 }
    299 
    300 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
    301     ConfigKey cfgKey;
    302     auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
    303     uint64_t bucketStartTimeNs = 10000000000;
    304     uint64_t bucketSizeNs =
    305             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
    306     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
    307     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
    308     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
    309     FeedEvents(config, processor);
    310     ConfigMetricsReportList reports;
    311     vector<uint8_t> buffer;
    312 
    313     std::vector<std::unique_ptr<LogEvent>> events;
    314     events.push_back(
    315             CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
    316                                           bucketStartTimeNs + 2 * bucketSizeNs + 90));
    317     events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
    318                                                 bucketStartTimeNs + 2 * bucketSizeNs + 100));
    319     events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
    320                                                 bucketStartTimeNs + 5 * bucketSizeNs + 100));
    321     sortLogEventsByTimestamp(&events);
    322     for (const auto& event : events) {
    323         processor->OnLogEvent(event.get());
    324     }
    325 
    326     processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
    327                             &buffer);
    328     EXPECT_TRUE(buffer.size() > 0);
    329     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
    330     backfillDimensionPath(&reports);
    331     backfillStringInReport(&reports);
    332     backfillStartEndTimestamp(&reports);
    333     EXPECT_EQ(reports.reports_size(), 1);
    334     EXPECT_EQ(reports.reports(0).metrics_size(), 1);
    335     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
    336     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
    337     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
    338     ValidateAttributionUidDimension(data.dimensions_in_what(),
    339                                     android::util::WAKELOCK_STATE_CHANGED, 111);
    340     // The last wakelock holding spans 4 buckets.
    341     EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
    342     EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
    343               bucketStartTimeNs + 5 * bucketSizeNs);
    344     EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
    345               bucketStartTimeNs + 6 * bucketSizeNs);
    346 }
    347 
    348 #else
    349 GTEST_LOG_(INFO) << "This test does nothing.\n";
    350 #endif
    351 
    352 }  // namespace statsd
    353 }  // namespace os
    354 }  // namespace android
    355