blob: e13bf1409989d817cd2bec59b0de180871036fdd [file] [log] [blame]
Yangster-mac20877162017-12-22 17:19:39 -08001// 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"
Yangster-macb8144812018-01-04 10:56:23 -080018#include "src/stats_log_util.h"
Yangster-mac20877162017-12-22 17:19:39 -080019#include "tests/statsd_test_util.h"
20
21#include <vector>
22
23namespace android {
24namespace os {
25namespace statsd {
26
27#ifdef __ANDROID__
28
Yangster-mac87718e22018-01-11 16:16:26 -080029namespace {
30
Yangster-mac20877162017-12-22 17:19:39 -080031StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
32 StatsdConfig config;
David Chen8faaa012018-02-28 15:54:36 -080033 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
Yangster-mac20877162017-12-22 17:19:39 -080034 *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.
David Chen27785a82018-01-19 17:06:45 -080044 FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
Yangster-mac20877162017-12-22 17:19:39 -080045 android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
David Chen27785a82018-01-19 17:06:45 -080046 // 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;
Yangster-mac20877162017-12-22 17:19:39 -080049 *config.add_predicate() = holdingWakelockPredicate;
50
51 auto durationMetric = config.add_duration_metric();
Yangster-mac94e197c2018-01-02 16:03:03 -080052 durationMetric->set_id(StringToId("WakelockDuration"));
53 durationMetric->set_what(holdingWakelockPredicate.id());
54 durationMetric->set_condition(screenIsOffPredicate.id());
Yangster-mac20877162017-12-22 17:19:39 -080055 durationMetric->set_aggregation_type(aggregationType);
56 // The metric is dimensioning by first attribution node and only by uid.
Yangster-mac468ff042018-01-17 12:26:34 -080057 *durationMetric->mutable_dimensions_in_what() =
Yangster-mac20877162017-12-22 17:19:39 -080058 CreateAttributionUidDimensions(
59 android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
yro59cc24d2018-02-13 20:17:32 -080060 durationMetric->set_bucket(FIVE_MINUTES);
Yangster-mac20877162017-12-22 17:19:39 -080061 return config;
62}
63
Yao Chen9c1debe2018-02-19 14:39:19 -080064std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
65 CreateAttribution(222, "GMSCoreModule1"),
66 CreateAttribution(222, "GMSCoreModule2")};
Yangster-mac87718e22018-01-11 16:16:26 -080067
Yao Chen9c1debe2018-02-19 14:39:19 -080068std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
69 CreateAttribution(222, "GMSCoreModule1"),
70 CreateAttribution(222, "GMSCoreModule2")};
David Chen27785a82018-01-19 17:06:45 -080071
72/*
73Events:
74Screen off is met from (200ns,1 min+500ns].
75Acquire event for wl1 from 2ns to 1min+2ns
76Acquire event for wl2 from 1min-10ns to 2min-15ns
77*/
78void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
79 uint64_t bucketStartTimeNs = 10000000000;
80 uint64_t bucketSizeNs =
Yangster-macb8144812018-01-04 10:56:23 -080081 TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
Yangster-mac20877162017-12-22 17:19:39 -080082
David Chen27785a82018-01-19 17:06:45 -080083 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 =
Bookatz1a1b0462018-01-12 11:47:03 -080088 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
Yangster-mac20877162017-12-22 17:19:39 -080089 bucketStartTimeNs + bucketSizeNs + 500);
90
David Chen27785a82018-01-19 17:06:45 -080091 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);
Yangster-mac20877162017-12-22 17:19:39 -080098
David Chen27785a82018-01-19 17:06:45 -080099 std::vector<std::unique_ptr<LogEvent>> events;
Yangster-mac20877162017-12-22 17:19:39 -0800100
David Chen27785a82018-01-19 17:06:45 -0800101 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));
Yangster-mac20877162017-12-22 17:19:39 -0800108
David Chen27785a82018-01-19 17:06:45 -0800109 sortLogEventsByTimestamp(&events);
Yangster-mac20877162017-12-22 17:19:39 -0800110
David Chen27785a82018-01-19 17:06:45 -0800111 for (const auto& event : events) {
112 processor->OnLogEvent(event.get());
Yangster-mac20877162017-12-22 17:19:39 -0800113 }
114}
115
David Chen27785a82018-01-19 17:06:45 -0800116} // namespace
117
Yao Chen8a8d16c2018-02-08 14:50:40 -0800118TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
David Chen27785a82018-01-19 17:06:45 -0800119 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;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700124 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
David Chen27785a82018-01-19 17:06:45 -0800125 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
126 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
127 FeedEvents(config, processor);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800128 vector<uint8_t> buffer;
David Chen27785a82018-01-19 17:06:45 -0800129 ConfigMetricsReportList reports;
Bookatzff71cad2018-09-20 17:17:49 -0700130 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000131 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800132 EXPECT_TRUE(buffer.size() > 0);
133 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700134 backfillDimensionPath(&reports);
135 backfillStringInReport(&reports);
136 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800137
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);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800153}
David Chen27785a82018-01-19 17:06:45 -0800154
Yao Chen8a8d16c2018-02-08 14:50:40 -0800155TEST(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;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700161 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800162 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;
Bookatzff71cad2018-09-20 17:17:49 -0700167 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000168 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800169 EXPECT_TRUE(buffer.size() > 0);
170 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700171 backfillDimensionPath(&reports);
172 backfillStringInReport(&reports);
173 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800174 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);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800179 auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
David Chen27785a82018-01-19 17:06:45 -0800180 // 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);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800191}
192TEST(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;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700198 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800199 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;
David Chen27785a82018-01-19 17:06:45 -0800204
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 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800217
Bookatzff71cad2018-09-20 17:17:49 -0700218 processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000219 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800220 EXPECT_TRUE(buffer.size() > 0);
221 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700222 backfillDimensionPath(&reports);
223 backfillStringInReport(&reports);
224 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800225 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);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800229 auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
David Chen27785a82018-01-19 17:06:45 -0800230 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
Yao Chen8a8d16c2018-02-08 14:50:40 -0800239TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
David Chen27785a82018-01-19 17:06:45 -0800240 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;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700245 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
David Chen27785a82018-01-19 17:06:45 -0800246 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
247 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
248 FeedEvents(config, processor);
249 ConfigMetricsReportList reports;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800250 vector<uint8_t> buffer;
Bookatzff71cad2018-09-20 17:17:49 -0700251 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000252 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800253 EXPECT_TRUE(buffer.size() > 0);
254
255 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700256 backfillDimensionPath(&reports);
257 backfillStringInReport(&reports);
258 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800259
260 EXPECT_EQ(reports.reports_size(), 1);
David Chen27785a82018-01-19 17:06:45 -0800261
Yao Chen8a8d16c2018-02-08 14:50:40 -0800262 // 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.
Yang Lub4722912018-11-15 11:02:03 -0800265 EXPECT_EQ(1, reports.reports(0).metrics_size());
266 EXPECT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
Yao Chen8a8d16c2018-02-08 14:50:40 -0800267}
268
269TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
270 ConfigKey cfgKey;
271 auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
272 uint64_t bucketStartTimeNs = 10000000000;
273 uint64_t bucketSizeNs =
274 TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700275 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800276 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
277 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
278 FeedEvents(config, processor);
279 ConfigMetricsReportList reports;
280 vector<uint8_t> buffer;
Bookatzff71cad2018-09-20 17:17:49 -0700281 processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000282 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800283 EXPECT_TRUE(buffer.size() > 0);
284 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700285 backfillDimensionPath(&reports);
286 backfillStringInReport(&reports);
287 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800288 EXPECT_EQ(reports.reports_size(), 1);
289 EXPECT_EQ(reports.reports(0).metrics_size(), 1);
290 EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
291 // Dump the report after the end of 2nd bucket. One dimension with one bucket.
292 EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
293 auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
294 // Validate dimension value.
295 ValidateAttributionUidDimension(data.dimensions_in_what(),
296 android::util::WAKELOCK_STATE_CHANGED, 111);
297 // The max is acquire event for wl1 to screen off start.
298 EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800299}
300
301TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
302 ConfigKey cfgKey;
303 auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
304 uint64_t bucketStartTimeNs = 10000000000;
305 uint64_t bucketSizeNs =
306 TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700307 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800308 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
309 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
310 FeedEvents(config, processor);
311 ConfigMetricsReportList reports;
312 vector<uint8_t> buffer;
David Chen27785a82018-01-19 17:06:45 -0800313
314 std::vector<std::unique_ptr<LogEvent>> events;
315 events.push_back(
316 CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
317 bucketStartTimeNs + 2 * bucketSizeNs + 90));
318 events.push_back(CreateAcquireWakelockEvent(attributions1, "wl3",
319 bucketStartTimeNs + 2 * bucketSizeNs + 100));
320 events.push_back(CreateReleaseWakelockEvent(attributions1, "wl3",
321 bucketStartTimeNs + 5 * bucketSizeNs + 100));
322 sortLogEventsByTimestamp(&events);
323 for (const auto& event : events) {
324 processor->OnLogEvent(event.get());
325 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800326
Bookatzff71cad2018-09-20 17:17:49 -0700327 processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000328 ADB_DUMP, FAST, &buffer);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800329 EXPECT_TRUE(buffer.size() > 0);
330 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700331 backfillDimensionPath(&reports);
332 backfillStringInReport(&reports);
333 backfillStartEndTimestamp(&reports);
David Chen27785a82018-01-19 17:06:45 -0800334 EXPECT_EQ(reports.reports_size(), 1);
335 EXPECT_EQ(reports.reports(0).metrics_size(), 1);
336 EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
337 EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800338 auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
David Chen27785a82018-01-19 17:06:45 -0800339 ValidateAttributionUidDimension(data.dimensions_in_what(),
340 android::util::WAKELOCK_STATE_CHANGED, 111);
341 // The last wakelock holding spans 4 buckets.
342 EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
Yangster-mac330af582018-02-08 15:24:38 -0800343 EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
David Chen27785a82018-01-19 17:06:45 -0800344 bucketStartTimeNs + 5 * bucketSizeNs);
Yangster-mac330af582018-02-08 15:24:38 -0800345 EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
David Chen27785a82018-01-19 17:06:45 -0800346 bucketStartTimeNs + 6 * bucketSizeNs);
347}
348
Yangster-mac20877162017-12-22 17:19:39 -0800349#else
350GTEST_LOG_(INFO) << "This test does nothing.\n";
351#endif
352
353} // namespace statsd
354} // namespace os
yro59cc24d2018-02-13 20:17:32 -0800355} // namespace android