12087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// Copyright (C) 2017 The Android Open Source Project
22087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac//
32087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// Licensed under the Apache License, Version 2.0 (the "License");
42087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// you may not use this file except in compliance with the License.
52087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// You may obtain a copy of the License at
62087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac//
72087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac//      http://www.apache.org/licenses/LICENSE-2.0
82087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac//
92087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// Unless required by applicable law or agreed to in writing, software
102087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// distributed under the License is distributed on an "AS IS" BASIS,
112087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// See the License for the specific language governing permissions and
132087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac// limitations under the License.
142087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
152087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include <gtest/gtest.h>
162087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
172087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include "src/StatsLogProcessor.h"
18b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac#include "src/stats_log_util.h"
192087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include "tests/statsd_test_util.h"
202087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
212087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include <vector>
222087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
232087716f2bdca90c7c3034d556ac12911bd8018eYangster-macnamespace android {
242087716f2bdca90c7c3034d556ac12911bd8018eYangster-macnamespace os {
252087716f2bdca90c7c3034d556ac12911bd8018eYangster-macnamespace statsd {
262087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
272087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#ifdef __ANDROID__
282087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
2987718e283a62660eaa0e39fd780c97a290da988fYangster-macnamespace {
3087718e283a62660eaa0e39fd780c97a290da988fYangster-mac
312087716f2bdca90c7c3034d556ac12911bd8018eYangster-macStatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
322087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    StatsdConfig config;
338faaa01489d81b815e62e4416e78e4b5500b487aDavid Chen    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
342087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
352087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
362087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
372087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
382087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
392087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
402087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_predicate() = screenIsOffPredicate;
412087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
422087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
432087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    // The predicate is dimensioning by any attribution node and both by uid and tag.
4427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
452087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
4627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Also slice by the wakelock tag
4727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
4827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
492087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    *config.add_predicate() = holdingWakelockPredicate;
502087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
512087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    auto durationMetric = config.add_duration_metric();
5294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    durationMetric->set_id(StringToId("WakelockDuration"));
5394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    durationMetric->set_what(holdingWakelockPredicate.id());
5494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    durationMetric->set_condition(screenIsOffPredicate.id());
552087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    durationMetric->set_aggregation_type(aggregationType);
562087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    // The metric is dimensioning by first attribution node and only by uid.
57468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-mac    *durationMetric->mutable_dimensions_in_what() =
582087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac        CreateAttributionUidDimensions(
592087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
6059cc24dbfda4148c1f5ef4de9c8763caa8672443yro    durationMetric->set_bucket(FIVE_MINUTES);
612087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    return config;
622087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac}
632087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
649c1debe330006b2b4d5c08a55905789c57369609Yao Chenstd::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
659c1debe330006b2b4d5c08a55905789c57369609Yao Chen                                                      CreateAttribution(222, "GMSCoreModule1"),
669c1debe330006b2b4d5c08a55905789c57369609Yao Chen                                                      CreateAttribution(222, "GMSCoreModule2")};
6727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
689c1debe330006b2b4d5c08a55905789c57369609Yao Chenstd::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
699c1debe330006b2b4d5c08a55905789c57369609Yao Chen                                                      CreateAttribution(222, "GMSCoreModule1"),
709c1debe330006b2b4d5c08a55905789c57369609Yao Chen                                                      CreateAttribution(222, "GMSCoreModule2")};
7127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
7227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen/*
7327785a8a4a684c831c18f7189a6fa1b98c3573e6David ChenEvents:
7427785a8a4a684c831c18f7189a6fa1b98c3573e6David ChenScreen off is met from (200ns,1 min+500ns].
7527785a8a4a684c831c18f7189a6fa1b98c3573e6David ChenAcquire event for wl1 from 2ns to 1min+2ns
7627785a8a4a684c831c18f7189a6fa1b98c3573e6David ChenAcquire event for wl2 from 1min-10ns to 2min-15ns
7727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen*/
7827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chenvoid FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
7927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketStartTimeNs = 10000000000;
8027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketSizeNs =
8127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
8227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
8327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
8427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            android::view::DisplayStateEnum::DISPLAY_STATE_ON, bucketStartTimeNs + 1);
8527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
8627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            android::view::DisplayStateEnum::DISPLAY_STATE_OFF, bucketStartTimeNs + 200);
8727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto screenTurnedOnEvent2 =
8827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
8927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                          bucketStartTimeNs + bucketSizeNs + 500);
9027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
9127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto acquireEvent1 = CreateAcquireWakelockEvent(attributions1, "wl1", bucketStartTimeNs + 2);
9227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto releaseEvent1 =
9327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            CreateReleaseWakelockEvent(attributions1, "wl1", bucketStartTimeNs + bucketSizeNs + 2);
9427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto acquireEvent2 =
9527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            CreateAcquireWakelockEvent(attributions2, "wl2", bucketStartTimeNs + bucketSizeNs - 10);
9627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto releaseEvent2 = CreateReleaseWakelockEvent(attributions2, "wl2",
9727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                                    bucketStartTimeNs + 2 * bucketSizeNs - 15);
9827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
9927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    std::vector<std::unique_ptr<LogEvent>> events;
10027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
10127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(screenTurnedOnEvent));
10227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(screenTurnedOffEvent));
10327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(screenTurnedOnEvent2));
10427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(acquireEvent1));
10527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(acquireEvent2));
10627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(releaseEvent1));
10727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(std::move(releaseEvent2));
10827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
10927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    sortLogEventsByTimestamp(&events);
11027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
11127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    for (const auto& event : events) {
11227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen        processor->OnLogEvent(event.get());
11327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    }
11427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen}
11527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
11687718e283a62660eaa0e39fd780c97a290da988fYangster-mac}  // namespace
11787718e283a62660eaa0e39fd780c97a290da988fYangster-mac
1188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
1192087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    ConfigKey cfgKey;
12027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto config = CreateStatsdConfig(DurationMetric::SUM);
12127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketStartTimeNs = 10000000000;
12227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketSizeNs =
123b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
12415f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
12527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
12627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
12727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    FeedEvents(config, processor);
1288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
12927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ConfigMetricsReportList reports;
13056ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
13156ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
1328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
1338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1349def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
1359def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
1369def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
1372087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
13827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
13927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
14027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
14127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
1422087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
14327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
14427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Validate dimension value.
14527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ValidateAttributionUidDimension(data.dimensions_in_what(),
14627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                    android::util::WAKELOCK_STATE_CHANGED, 111);
14727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Validate bucket info.
14827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
14927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    data = reports.reports(0).metrics(0).duration_metrics().data(0);
15027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The wakelock holding interval starts from the screen off event and to the end of the 1st
15127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // bucket.
15227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
1538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
15427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
1558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
1568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigKey cfgKey;
1578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto config = CreateStatsdConfig(DurationMetric::SUM);
1588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketStartTimeNs = 10000000000;
1598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketSizeNs =
1608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
16115f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
1628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
1638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
1648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FeedEvents(config, processor);
1658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
1668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigMetricsReportList reports;
16756ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
16856ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
1698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
1708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1719def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
1729def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
1739def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
17427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
17527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
17627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
17727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Dump the report after the end of 2nd bucket.
17827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
1798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
18027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Validate dimension value.
18127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ValidateAttributionUidDimension(data.dimensions_in_what(),
18227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                    android::util::WAKELOCK_STATE_CHANGED, 111);
18327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Two output buckets.
18427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The wakelock holding interval in the 1st bucket starts from the screen off event and to
18527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // the end of the 1st bucket.
18627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
18727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen              bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
18827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
18927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // ends at the second screen on event.
19027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
1918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
1928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
1938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigKey cfgKey;
1948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto config = CreateStatsdConfig(DurationMetric::SUM);
1958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketStartTimeNs = 10000000000;
1968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketSizeNs =
1978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
19815f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
1998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
2008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
2018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FeedEvents(config, processor);
2028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
2038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigMetricsReportList reports;
20427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
20527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    std::vector<std::unique_ptr<LogEvent>> events;
20627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(
2071a1b0464cb43903ed540f4c43fd423b16e398c04Bookatz            CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
20827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                          bucketStartTimeNs + 2 * bucketSizeNs + 90));
20927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
21027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                                bucketStartTimeNs + 2 * bucketSizeNs + 100));
21127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
21227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                                bucketStartTimeNs + 5 * bucketSizeNs + 100));
21327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    sortLogEventsByTimestamp(&events);
21427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    for (const auto& event : events) {
21527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen        processor->OnLogEvent(event.get());
21627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    }
2178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
21856ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
21956ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
2208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
2218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
2229def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
2239def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
2249def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
22527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
22627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
22727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
22827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
2298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
23027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ValidateAttributionUidDimension(data.dimensions_in_what(),
23127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                    android::util::WAKELOCK_STATE_CHANGED, 111);
23227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The last wakelock holding spans 4 buckets.
23327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
23427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
23527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
23627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
23727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen}
2382087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
2398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
24027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ConfigKey cfgKey;
24127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
24227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketStartTimeNs = 10000000000;
24327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    uint64_t bucketSizeNs =
24427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
24515f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
24627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
24727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
24827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    FeedEvents(config, processor);
24927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ConfigMetricsReportList reports;
2508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
25156ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
25256ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
2538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
2548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
2569def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
2579def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
2589def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
25927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
26027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
26127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
2628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
2638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
2648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // itself.
2658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_EQ(0, reports.reports(0).metrics_size());
2668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
2678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
2698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigKey cfgKey;
2708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
2718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketStartTimeNs = 10000000000;
2728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketSizeNs =
2738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
27415f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
2758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
2768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
2778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FeedEvents(config, processor);
2788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigMetricsReportList reports;
2798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
28056ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
28156ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
2828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
2838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
2849def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
2859def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
2869def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
28727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
28827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
28927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
29027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Dump the report after the end of 2nd bucket. One dimension with one bucket.
29127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
29227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
29327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // Validate dimension value.
29427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ValidateAttributionUidDimension(data.dimensions_in_what(),
29527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                    android::util::WAKELOCK_STATE_CHANGED, 111);
29627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The max is acquire event for wl1 to screen off start.
29727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
2988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
2998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao ChenTEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
3018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigKey cfgKey;
3028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
3038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketStartTimeNs = 10000000000;
3048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    uint64_t bucketSizeNs =
3058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
30615f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
3078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
3088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
3098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FeedEvents(config, processor);
3108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    ConfigMetricsReportList reports;
3118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    vector<uint8_t> buffer;
31227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
31327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    std::vector<std::unique_ptr<LogEvent>> events;
31427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(
31527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen            CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
31627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                          bucketStartTimeNs + 2 * bucketSizeNs + 90));
31727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
31827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                                bucketStartTimeNs + 2 * bucketSizeNs + 100));
31927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
32027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                                bucketStartTimeNs + 5 * bucketSizeNs + 100));
32127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    sortLogEventsByTimestamp(&events);
32227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    for (const auto& event : events) {
32327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen        processor->OnLogEvent(event.get());
3242087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac    }
3258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
32656ae0d9a48212c6e886e5887a6f9191f3020af40David Chen    processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
32756ae0d9a48212c6e886e5887a6f9191f3020af40David Chen                            &buffer);
3288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(buffer.size() > 0);
3298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
3309def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillDimensionPath(&reports);
3319def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStringInReport(&reports);
3329def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    backfillStartEndTimestamp(&reports);
33327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports_size(), 1);
33427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
33527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
33627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
3378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
33827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    ValidateAttributionUidDimension(data.dimensions_in_what(),
33927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                                    android::util::WAKELOCK_STATE_CHANGED, 111);
34027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The last wakelock holding spans 4 buckets.
34127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
342330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac    EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
34327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen              bucketStartTimeNs + 5 * bucketSizeNs);
344330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac    EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
34527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen              bucketStartTimeNs + 6 * bucketSizeNs);
3462087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac}
3472087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
3482087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#else
3492087716f2bdca90c7c3034d556ac12911bd8018eYangster-macGTEST_LOG_(INFO) << "This test does nothing.\n";
3502087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#endif
3512087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac
3522087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac}  // namespace statsd
3532087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac}  // namespace os
35459cc24dbfda4148c1f5ef4de9c8763caa8672443yro}  // namespace android
355