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 <android/binder_interface_utils.h>
16 #include <gtest/gtest.h>
17
18 #include <vector>
19
20 #include "src/StatsLogProcessor.h"
21 #include "src/stats_log_util.h"
22 #include "tests/statsd_test_util.h"
23
24 using ::ndk::SharedRefBase;
25
26 namespace android {
27 namespace os {
28 namespace statsd {
29
30 #ifdef __ANDROID__
31
32 namespace {
33
34 const int64_t metricId = 123456;
35 const int32_t ATOM_TAG = util::SUBSYSTEM_SLEEP_STATE;
36
CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,bool useCondition=true)37 StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
38 bool useCondition = true) {
39 StatsdConfig config;
40 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
41 config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
42 auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
43 *config.add_atom_matcher() = atomMatcher;
44 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
45 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
46
47 auto screenIsOffPredicate = CreateScreenIsOffPredicate();
48 *config.add_predicate() = screenIsOffPredicate;
49
50 auto gaugeMetric = config.add_gauge_metric();
51 gaugeMetric->set_id(metricId);
52 gaugeMetric->set_what(atomMatcher.id());
53 if (useCondition) {
54 gaugeMetric->set_condition(screenIsOffPredicate.id());
55 }
56 gaugeMetric->set_sampling_type(sampling_type);
57 gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
58 *gaugeMetric->mutable_dimensions_in_what() =
59 CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
60 gaugeMetric->set_bucket(FIVE_MINUTES);
61 gaugeMetric->set_max_pull_delay_sec(INT_MAX);
62 config.set_hash_strings_in_metric_report(false);
63 gaugeMetric->set_split_bucket_for_app_upgrade(true);
64 gaugeMetric->set_min_bucket_size_nanos(1000);
65
66 return config;
67 }
68
69 } // namespaces
70
TEST(GaugeMetricE2ePulledTest,TestRandomSamplePulledEvents)71 TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents) {
72 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
73 int64_t baseTimeNs = getElapsedRealtimeNs();
74 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
75 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
76
77 ConfigKey cfgKey;
78 auto processor =
79 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
80 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
81 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
82 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
83 processor->mPullerManager->ForceClearPullerCache();
84
85 int startBucketNum = processor->mMetricsManagers.begin()
86 ->second->mAllMetricProducers[0]
87 ->getCurrentBucketNum();
88 EXPECT_GT(startBucketNum, (int64_t)0);
89
90 // When creating the config, the gauge metric producer should register the alarm at the
91 // end of the current bucket.
92 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
93 EXPECT_EQ(bucketSizeNs,
94 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
95 int64_t& nextPullTimeNs =
96 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
97 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
98
99 auto screenOffEvent =
100 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
101 processor->OnLogEvent(screenOffEvent.get());
102
103 // Pulling alarm arrives on time and reset the sequential pulling alarm.
104 processor->informPullAlarmFired(nextPullTimeNs + 1);
105 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
106
107 auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
108 android::view::DISPLAY_STATE_ON);
109 processor->OnLogEvent(screenOnEvent.get());
110
111 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
112 android::view::DISPLAY_STATE_OFF);
113 processor->OnLogEvent(screenOffEvent.get());
114
115 processor->informPullAlarmFired(nextPullTimeNs + 1);
116 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
117
118 processor->informPullAlarmFired(nextPullTimeNs + 1);
119 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
120
121 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
122 android::view::DISPLAY_STATE_ON);
123 processor->OnLogEvent(screenOnEvent.get());
124
125 processor->informPullAlarmFired(nextPullTimeNs + 3);
126 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
127
128 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
129 android::view::DISPLAY_STATE_OFF);
130 processor->OnLogEvent(screenOffEvent.get());
131
132 processor->informPullAlarmFired(nextPullTimeNs + 2);
133 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
134
135 processor->informPullAlarmFired(nextPullTimeNs + 2);
136
137 ConfigMetricsReportList reports;
138 vector<uint8_t> buffer;
139 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
140 ADB_DUMP, FAST, &buffer);
141 EXPECT_TRUE(buffer.size() > 0);
142 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
143 backfillDimensionPath(&reports);
144 backfillStringInReport(&reports);
145 backfillStartEndTimestamp(&reports);
146 backfillAggregatedAtoms(&reports);
147 ASSERT_EQ(1, reports.reports_size());
148 ASSERT_EQ(1, reports.reports(0).metrics_size());
149 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
150 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
151 ASSERT_GT((int)gaugeMetrics.data_size(), 1);
152
153 auto data = gaugeMetrics.data(0);
154 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
155 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
156 EXPECT_EQ(1 /* subsystem name field */,
157 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
158 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
159 ASSERT_EQ(6, data.bucket_info_size());
160
161 ASSERT_EQ(1, data.bucket_info(0).atom_size());
162 ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
163 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
164 ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
165 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
166 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
167 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
168 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
169
170 ASSERT_EQ(1, data.bucket_info(1).atom_size());
171 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
172 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
173 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
174 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
175 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
176 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
177
178 ASSERT_EQ(1, data.bucket_info(2).atom_size());
179 ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
180 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
181 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
182 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
183 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
184 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
185
186 ASSERT_EQ(1, data.bucket_info(3).atom_size());
187 ASSERT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
188 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
189 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
190 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
191 EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
192 EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
193
194 ASSERT_EQ(1, data.bucket_info(4).atom_size());
195 ASSERT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
196 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
197 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
198 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
199 EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
200 EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
201
202 ASSERT_EQ(1, data.bucket_info(5).atom_size());
203 ASSERT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
204 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
205 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
206 EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
207 EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
208 EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
209 }
210
TEST(GaugeMetricE2ePulledTest,TestFirstNSamplesPulledNoTrigger)211 TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTrigger) {
212 StatsdConfig config = CreateStatsdConfig(GaugeMetric::FIRST_N_SAMPLES);
213 auto gaugeMetric = config.mutable_gauge_metric(0);
214 gaugeMetric->set_max_num_gauge_atoms_per_bucket(3);
215 int64_t baseTimeNs = getElapsedRealtimeNs();
216 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
217 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
218
219 ConfigKey cfgKey;
220 auto processor =
221 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
222 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
223 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
224 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
225 processor->mPullerManager->ForceClearPullerCache();
226
227 // When creating the config, the gauge metric producer should register the alarm at the
228 // end of the current bucket.
229 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
230 EXPECT_EQ(bucketSizeNs,
231 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
232 int64_t& nextPullTimeNs =
233 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
234
235 auto screenOffEvent =
236 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
237 processor->OnLogEvent(screenOffEvent.get());
238
239 auto screenOnEvent =
240 CreateScreenStateChangedEvent(configAddedTimeNs + 100, android::view::DISPLAY_STATE_ON);
241 processor->OnLogEvent(screenOnEvent.get());
242
243 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 150,
244 android::view::DISPLAY_STATE_OFF);
245 processor->OnLogEvent(screenOffEvent.get());
246
247 screenOnEvent =
248 CreateScreenStateChangedEvent(configAddedTimeNs + 200, android::view::DISPLAY_STATE_ON);
249 processor->OnLogEvent(screenOnEvent.get());
250
251 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 250,
252 android::view::DISPLAY_STATE_OFF);
253 processor->OnLogEvent(screenOffEvent.get());
254
255 screenOnEvent =
256 CreateScreenStateChangedEvent(configAddedTimeNs + 300, android::view::DISPLAY_STATE_ON);
257 processor->OnLogEvent(screenOnEvent.get());
258
259 // Not logged. max_num_gauge_atoms_per_bucket already hit.
260 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 325,
261 android::view::DISPLAY_STATE_OFF);
262 processor->OnLogEvent(screenOffEvent.get());
263
264 // Pulling alarm arrives on time and reset the sequential pulling alarm.
265 processor->informPullAlarmFired(nextPullTimeNs + 1);
266
267 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
268 android::view::DISPLAY_STATE_ON);
269 processor->OnLogEvent(screenOnEvent.get());
270
271 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
272 android::view::DISPLAY_STATE_OFF);
273 processor->OnLogEvent(screenOffEvent.get());
274
275 processor->informPullAlarmFired(nextPullTimeNs + 2);
276
277 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + (3 * bucketSizeNs) + 15,
278 android::view::DISPLAY_STATE_ON);
279 processor->OnLogEvent(screenOnEvent.get());
280
281 processor->informPullAlarmFired(nextPullTimeNs + 4);
282
283 ConfigMetricsReportList reports;
284 vector<uint8_t> buffer;
285 processor->onDumpReport(cfgKey, configAddedTimeNs + (4 * bucketSizeNs) + 10, false, true,
286 ADB_DUMP, FAST, &buffer);
287 EXPECT_TRUE(buffer.size() > 0);
288 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
289 backfillDimensionPath(&reports);
290 backfillStringInReport(&reports);
291 backfillStartEndTimestamp(&reports);
292 backfillAggregatedAtoms(&reports);
293 ASSERT_EQ(1, reports.reports_size());
294 ASSERT_EQ(1, reports.reports(0).metrics_size());
295 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
296 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
297 ASSERT_GT((int)gaugeMetrics.data_size(), 1);
298
299 auto data = gaugeMetrics.data(1);
300 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
301 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
302 EXPECT_EQ(1 /* subsystem name field */,
303 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
304 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
305 ASSERT_EQ(3, data.bucket_info_size());
306
307 ASSERT_EQ(3, data.bucket_info(0).atom_size());
308 ASSERT_EQ(3, data.bucket_info(0).elapsed_timestamp_nanos_size());
309 ValidateGaugeBucketTimes(data.bucket_info(0),
310 /*startTimeNs=*/configAddedTimeNs,
311 /*endTimeNs=*/configAddedTimeNs + bucketSizeNs,
312 /*eventTimesNs=*/
313 {(int64_t)(configAddedTimeNs + 55), (int64_t)(configAddedTimeNs + 150),
314 (int64_t)(configAddedTimeNs + 250)});
315
316 ASSERT_EQ(2, data.bucket_info(1).atom_size());
317 ASSERT_EQ(2, data.bucket_info(1).elapsed_timestamp_nanos_size());
318 ValidateGaugeBucketTimes(data.bucket_info(1),
319 /*startTimeNs=*/configAddedTimeNs + bucketSizeNs,
320 /*endTimeNs=*/configAddedTimeNs + (2 * bucketSizeNs),
321 /*eventTimesNs=*/
322 {(int64_t)(configAddedTimeNs + bucketSizeNs + 1),
323 (int64_t)(configAddedTimeNs + bucketSizeNs + 100)});
324
325 ASSERT_EQ(1, data.bucket_info(2).atom_size());
326 ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
327 ValidateGaugeBucketTimes(
328 data.bucket_info(2), /*startTimeNs=*/configAddedTimeNs + (2 * bucketSizeNs),
329 /*endTimeNs=*/configAddedTimeNs + (3 * bucketSizeNs),
330 /*eventTimesNs=*/{(int64_t)(configAddedTimeNs + (2 * bucketSizeNs) + 2)});
331 }
332
TEST(GaugeMetricE2ePulledTest,TestConditionChangeToTrueSamplePulledEvents)333 TEST(GaugeMetricE2ePulledTest, TestConditionChangeToTrueSamplePulledEvents) {
334 auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
335 int64_t baseTimeNs = getElapsedRealtimeNs();
336 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
337 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
338
339 ConfigKey cfgKey;
340 auto processor =
341 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
342 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
343 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
344 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
345 processor->mPullerManager->ForceClearPullerCache();
346
347 int startBucketNum = processor->mMetricsManagers.begin()
348 ->second->mAllMetricProducers[0]
349 ->getCurrentBucketNum();
350 EXPECT_GT(startBucketNum, (int64_t)0);
351
352 auto screenOffEvent =
353 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
354 processor->OnLogEvent(screenOffEvent.get());
355
356 auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
357 android::view::DISPLAY_STATE_ON);
358 processor->OnLogEvent(screenOnEvent.get());
359
360 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
361 android::view::DISPLAY_STATE_OFF);
362 processor->OnLogEvent(screenOffEvent.get());
363
364 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
365 android::view::DISPLAY_STATE_ON);
366 processor->OnLogEvent(screenOnEvent.get());
367
368 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
369 android::view::DISPLAY_STATE_OFF);
370 processor->OnLogEvent(screenOffEvent.get());
371 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 3,
372 android::view::DISPLAY_STATE_ON);
373 processor->OnLogEvent(screenOnEvent.get());
374 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 10,
375 android::view::DISPLAY_STATE_OFF);
376 processor->OnLogEvent(screenOffEvent.get());
377
378 ConfigMetricsReportList reports;
379 vector<uint8_t> buffer;
380 processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
381 ADB_DUMP, FAST, &buffer);
382 EXPECT_TRUE(buffer.size() > 0);
383 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
384 backfillDimensionPath(&reports);
385 backfillStringInReport(&reports);
386 backfillStartEndTimestamp(&reports);
387 backfillAggregatedAtoms(&reports);
388 ASSERT_EQ(1, reports.reports_size());
389 ASSERT_EQ(1, reports.reports(0).metrics_size());
390 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
391 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
392 ASSERT_GT((int)gaugeMetrics.data_size(), 1);
393
394 auto data = gaugeMetrics.data(0);
395 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
396 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
397 EXPECT_EQ(1 /* subsystem name field */,
398 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
399 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
400 ASSERT_EQ(3, data.bucket_info_size());
401
402 ASSERT_EQ(1, data.bucket_info(0).atom_size());
403 ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
404 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
405 ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
406 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
407 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
408 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
409 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
410
411 ASSERT_EQ(1, data.bucket_info(1).atom_size());
412 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
413 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
414 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
415 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
416 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
417 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
418
419 ASSERT_EQ(2, data.bucket_info(2).atom_size());
420 ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
421 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
422 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
423 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
424 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
425 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
426 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
427 EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
428 EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
429 }
430
TEST(GaugeMetricE2ePulledTest,TestRandomSamplePulledEvent_LateAlarm)431 TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm) {
432 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
433 int64_t baseTimeNs = getElapsedRealtimeNs();
434 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
435 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
436
437 ConfigKey cfgKey;
438 auto processor =
439 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
440 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
441 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
442 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
443 processor->mPullerManager->ForceClearPullerCache();
444
445 int startBucketNum = processor->mMetricsManagers.begin()
446 ->second->mAllMetricProducers[0]
447 ->getCurrentBucketNum();
448 EXPECT_GT(startBucketNum, (int64_t)0);
449
450 // When creating the config, the gauge metric producer should register the alarm at the
451 // end of the current bucket.
452 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
453 EXPECT_EQ(bucketSizeNs,
454 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
455 int64_t& nextPullTimeNs =
456 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
457 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
458
459 auto screenOffEvent =
460 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
461 processor->OnLogEvent(screenOffEvent.get());
462
463 auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
464 android::view::DISPLAY_STATE_ON);
465 processor->OnLogEvent(screenOnEvent.get());
466
467 // Pulling alarm arrives one bucket size late.
468 processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
469 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
470
471 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 11,
472 android::view::DISPLAY_STATE_OFF);
473 processor->OnLogEvent(screenOffEvent.get());
474
475 // Pulling alarm arrives more than one bucket size late.
476 processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
477 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
478
479 ConfigMetricsReportList reports;
480 vector<uint8_t> buffer;
481 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
482 ADB_DUMP, FAST, &buffer);
483 EXPECT_TRUE(buffer.size() > 0);
484 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
485 backfillDimensionPath(&reports);
486 backfillStringInReport(&reports);
487 backfillStartEndTimestamp(&reports);
488 backfillAggregatedAtoms(&reports);
489 ASSERT_EQ(1, reports.reports_size());
490 ASSERT_EQ(1, reports.reports(0).metrics_size());
491 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
492 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
493 ASSERT_GT((int)gaugeMetrics.data_size(), 1);
494
495 auto data = gaugeMetrics.data(0);
496 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
497 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
498 EXPECT_EQ(1 /* subsystem name field */,
499 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
500 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
501 ASSERT_EQ(3, data.bucket_info_size());
502
503 ASSERT_EQ(1, data.bucket_info(0).atom_size());
504 ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
505 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
506 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
507 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
508 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
509 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
510
511 ASSERT_EQ(1, data.bucket_info(1).atom_size());
512 EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
513 data.bucket_info(1).elapsed_timestamp_nanos(0));
514 EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
515 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
516 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
517 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
518 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
519
520 ASSERT_EQ(1, data.bucket_info(2).atom_size());
521 ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
522 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
523 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
524 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
525 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
526 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
527 }
528
TEST(GaugeMetricE2ePulledTest,TestRandomSamplePulledEventsWithActivation)529 TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation) {
530 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
531
532 int64_t baseTimeNs = getElapsedRealtimeNs();
533 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
534 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
535
536 auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
537 *config.add_atom_matcher() = batterySaverStartMatcher;
538 const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
539 auto metric_activation = config.add_metric_activation();
540 metric_activation->set_metric_id(metricId);
541 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
542 auto event_activation = metric_activation->add_event_activation();
543 event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
544 event_activation->set_ttl_seconds(ttlNs / 1000000000);
545
546 StatsdStats::getInstance().reset();
547
548 ConfigKey cfgKey;
549 auto processor =
550 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
551 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
552 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
553 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
554 processor->mPullerManager->ForceClearPullerCache();
555
556 const int startBucketNum = processor->mMetricsManagers.begin()
557 ->second->mAllMetricProducers[0]
558 ->getCurrentBucketNum();
559 EXPECT_EQ(startBucketNum, 2);
560 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
561
562 // When creating the config, the gauge metric producer should register the alarm at the
563 // end of the current bucket.
564 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
565 EXPECT_EQ(bucketSizeNs,
566 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
567 int64_t& nextPullTimeNs =
568 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
569 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
570
571 // Check no pull occurred on metric initialization when it's not active.
572 const int64_t metricInitTimeNs = configAddedTimeNs + 1; // 10 mins + 1 ns.
573 processor->onStatsdInitCompleted(metricInitTimeNs);
574 StatsdStatsReport_PulledAtomStats pulledAtomStats =
575 getPulledAtomStats(util::SUBSYSTEM_SLEEP_STATE);
576 EXPECT_EQ(pulledAtomStats.atom_id(), ATOM_TAG);
577 EXPECT_EQ(pulledAtomStats.total_pull(), 0);
578
579 // Check no pull occurred on app upgrade when metric is not active.
580 const int64_t appUpgradeTimeNs = metricInitTimeNs + 1; // 10 mins + 2 ns.
581 processor->notifyAppUpgrade(appUpgradeTimeNs, "appName", 1000 /* uid */, 2 /* version */);
582 pulledAtomStats = getPulledAtomStats(util::SUBSYSTEM_SLEEP_STATE);
583 EXPECT_EQ(pulledAtomStats.atom_id(), ATOM_TAG);
584 EXPECT_EQ(pulledAtomStats.total_pull(), 0);
585
586 // Check skipped bucket is not added when metric is not active.
587 int64_t dumpReportTimeNs = appUpgradeTimeNs + 1; // 10 mins + 3 ns.
588 vector<uint8_t> buffer;
589 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
590 true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &buffer);
591 ConfigMetricsReportList reports;
592 EXPECT_TRUE(buffer.size() > 0);
593 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
594 ASSERT_EQ(1, reports.reports_size());
595 ASSERT_EQ(1, reports.reports(0).metrics_size());
596 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics =
597 reports.reports(0).metrics(0).gauge_metrics();
598 EXPECT_EQ(gaugeMetrics.skipped_size(), 0);
599
600 // Pulling alarm arrives on time and reset the sequential pulling alarm.
601 // Event should not be kept.
602 processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
603 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
604 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
605
606 // Activate the metric. A pull occurs upon activation. The event is kept. 1 total
607 // 15 mins + 2 ms
608 const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
609 auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
610 processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
611 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
612
613 // This event should be kept. 2 total.
614 processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
615 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
616
617 // This event should be kept. 3 total.
618 processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
619 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
620
621 // Create random event to deactivate metric.
622 // A pull should not occur here. 3 total.
623 // 25 mins + 2 ms + 1 ns.
624 const int64_t deactivationNs = activationNs + ttlNs + 1;
625 auto deactivationEvent = CreateScreenBrightnessChangedEvent(deactivationNs, 50);
626 processor->OnLogEvent(deactivationEvent.get());
627 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
628
629 // Event should not be kept. 3 total.
630 // 30 mins + 3 ns.
631 processor->informPullAlarmFired(nextPullTimeNs + 3);
632 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
633
634 // Event should not be kept. 3 total.
635 // 35 mins + 2 ns.
636 processor->informPullAlarmFired(nextPullTimeNs + 2);
637 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
638
639 buffer.clear();
640 // 40 mins + 10 ns.
641 processor->onDumpReport(cfgKey, configAddedTimeNs + 6 * bucketSizeNs + 10,
642 false /* include_current_partial_bucket */, true /* erase_data */,
643 ADB_DUMP, FAST, &buffer);
644 EXPECT_TRUE(buffer.size() > 0);
645 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
646 backfillDimensionPath(&reports);
647 backfillStringInReport(&reports);
648 backfillStartEndTimestamp(&reports);
649 backfillAggregatedAtoms(&reports);
650 ASSERT_EQ(1, reports.reports_size());
651 ASSERT_EQ(1, reports.reports(0).metrics_size());
652 gaugeMetrics = StatsLogReport::GaugeMetricDataWrapper();
653 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
654 ASSERT_GT((int)gaugeMetrics.data_size(), 0);
655
656 auto data = gaugeMetrics.data(0);
657 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
658 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
659 EXPECT_EQ(1 /* subsystem name field */,
660 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
661 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
662 ASSERT_EQ(3, data.bucket_info_size());
663
664 auto bucketInfo = data.bucket_info(0);
665 ASSERT_EQ(1, bucketInfo.atom_size());
666 ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
667 EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
668 ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
669 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
670 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
671 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
672 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
673
674 bucketInfo = data.bucket_info(1);
675 ASSERT_EQ(1, bucketInfo.atom_size());
676 ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
677 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
678 ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
679 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
680 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
681 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
682 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
683
684 bucketInfo = data.bucket_info(2);
685 ASSERT_EQ(1, bucketInfo.atom_size());
686 ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
687 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
688 ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
689 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
690 bucketInfo.start_bucket_elapsed_nanos());
691 EXPECT_EQ(MillisToNano(NanoToMillis(deactivationNs)), bucketInfo.end_bucket_elapsed_nanos());
692 EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
693 EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
694
695 // Check skipped bucket is not added after deactivation.
696 dumpReportTimeNs = configAddedTimeNs + 8 * bucketSizeNs + 10;
697 buffer.clear();
698 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
699 true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &buffer);
700 EXPECT_TRUE(buffer.size() > 0);
701 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
702 ASSERT_EQ(1, reports.reports_size());
703 ASSERT_EQ(1, reports.reports(0).metrics_size());
704 gaugeMetrics = reports.reports(0).metrics(0).gauge_metrics();
705 EXPECT_EQ(gaugeMetrics.skipped_size(), 0);
706 }
707
TEST(GaugeMetricE2ePulledTest,TestFirstNSamplesPulledNoTriggerWithActivation)708 TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTriggerWithActivation) {
709 StatsdConfig config = CreateStatsdConfig(GaugeMetric::FIRST_N_SAMPLES);
710 auto gaugeMetric = config.mutable_gauge_metric(0);
711 gaugeMetric->set_max_num_gauge_atoms_per_bucket(2);
712 int64_t baseTimeNs = getElapsedRealtimeNs();
713 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
714 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
715
716 auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
717 *config.add_atom_matcher() = batterySaverStartMatcher;
718 const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
719 auto metric_activation = config.add_metric_activation();
720 metric_activation->set_metric_id(metricId);
721 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
722 auto event_activation = metric_activation->add_event_activation();
723 event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
724 event_activation->set_ttl_seconds(ttlNs / NS_PER_SEC);
725
726 StatsdStats::getInstance().reset();
727
728 ConfigKey cfgKey;
729 auto processor =
730 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
731 SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
732 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
733 processor->mPullerManager->ForceClearPullerCache();
734
735 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
736
737 // When creating the config, the gauge metric producer should register the alarm at the
738 // end of the current bucket.
739 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
740 EXPECT_EQ(bucketSizeNs,
741 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
742 int64_t& nextPullTimeNs =
743 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
744
745 // Condition true but Active false
746 auto screenOffEvent =
747 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
748 processor->OnLogEvent(screenOffEvent.get());
749
750 auto screenOnEvent =
751 CreateScreenStateChangedEvent(configAddedTimeNs + 100, android::view::DISPLAY_STATE_ON);
752 processor->OnLogEvent(screenOnEvent.get());
753
754 // Pulling alarm arrives on time and reset the sequential pulling alarm.
755 // Event should not be kept.
756 processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
757 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
758
759 // Activate the metric. A pull occurs upon activation. The event is not kept. 0 total
760 // 15 mins + 1000 ns.
761 const int64_t activationNs = configAddedTimeNs + bucketSizeNs + 1000;
762 auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
763 processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 1000 ns.
764 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
765
766 // A pull occurs upon condition change. The event is kept. 1 total. 1 in bucket
767 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 150,
768 android::view::DISPLAY_STATE_OFF);
769 processor->OnLogEvent(screenOffEvent.get());
770
771 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 200,
772 android::view::DISPLAY_STATE_ON);
773 processor->OnLogEvent(screenOnEvent.get());
774
775 // A pull occurs upon condition change. The event is kept. 1 total. 2 in bucket
776 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 250,
777 android::view::DISPLAY_STATE_OFF);
778 processor->OnLogEvent(screenOffEvent.get());
779
780 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 300,
781 android::view::DISPLAY_STATE_ON);
782 processor->OnLogEvent(screenOnEvent.get());
783
784 // A pull occurs upon condition change. The event is not kept due to
785 // max_num_gauge_atoms_per_bucket. 1 total. 2 total in bucket
786 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 325,
787 android::view::DISPLAY_STATE_OFF);
788 processor->OnLogEvent(screenOffEvent.get());
789
790 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 375,
791 android::view::DISPLAY_STATE_ON);
792 processor->OnLogEvent(screenOnEvent.get());
793 // Condition false but Active true
794
795 // This event should not be kept. 1 total.
796 processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
797
798 // This event should not be kept. 1 total.
799 processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
800
801 // A pull occurs upon condition change. The event is kept. 2 total. 1 in bucket
802 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 50,
803 android::view::DISPLAY_STATE_OFF);
804 processor->OnLogEvent(screenOffEvent.get());
805 // Condition true but Active true
806
807 // Create random event to deactivate metric.
808 // A pull should not occur here. 2 total. 1 in bucket.
809 // 25 mins + 1000 ns + 1 ns.
810 const int64_t deactivationNs = activationNs + ttlNs + 1;
811 auto deactivationEvent = CreateScreenBrightnessChangedEvent(deactivationNs, 50);
812 processor->OnLogEvent(deactivationEvent.get());
813 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
814 // Condition true but Active false
815
816 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 50,
817 android::view::DISPLAY_STATE_ON);
818 processor->OnLogEvent(screenOnEvent.get());
819
820 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 100,
821 android::view::DISPLAY_STATE_OFF);
822 processor->OnLogEvent(screenOffEvent.get());
823
824 vector<uint8_t> buffer;
825 // 30 mins + 10 ns.
826 processor->onDumpReport(cfgKey, configAddedTimeNs + 4 * bucketSizeNs + 10,
827 false /* include_current_partial_bucket */, true /* erase_data */,
828 ADB_DUMP, FAST, &buffer);
829 ConfigMetricsReportList reports;
830 EXPECT_TRUE(buffer.size() > 0);
831 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
832 backfillDimensionPath(&reports);
833 backfillStringInReport(&reports);
834 backfillStartEndTimestamp(&reports);
835 backfillAggregatedAtoms(&reports);
836 ASSERT_EQ(1, reports.reports_size());
837 ASSERT_EQ(1, reports.reports(0).metrics_size());
838 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics = StatsLogReport::GaugeMetricDataWrapper();
839 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
840 ASSERT_GT((int)gaugeMetrics.data_size(), 0);
841
842 auto data = gaugeMetrics.data(0);
843 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
844 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
845 EXPECT_EQ(1 /* subsystem name field */,
846 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
847 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
848 ASSERT_EQ(2, data.bucket_info_size());
849
850 ASSERT_EQ(2, data.bucket_info(0).atom_size());
851 ASSERT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
852 ValidateGaugeBucketTimes(data.bucket_info(0),
853 /*startTimeNs=*/configAddedTimeNs + bucketSizeNs,
854 /*endTimeNs=*/configAddedTimeNs + (2 * bucketSizeNs),
855 /*eventTimesNs=*/
856 {(int64_t)(configAddedTimeNs + bucketSizeNs + 150),
857 (int64_t)(configAddedTimeNs + bucketSizeNs + 250)});
858
859 ASSERT_EQ(1, data.bucket_info(1).atom_size());
860 ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
861 ValidateGaugeBucketTimes(data.bucket_info(1),
862 /*startTimeNs=*/
863 MillisToNano(NanoToMillis(configAddedTimeNs + (3 * bucketSizeNs))),
864 /*endTimeNs=*/MillisToNano(NanoToMillis(deactivationNs)),
865 /*eventTimesNs=*/
866 {(int64_t)(configAddedTimeNs + (3 * bucketSizeNs) + 50)});
867 }
868
TEST(GaugeMetricE2ePulledTest,TestRandomSamplePulledEventsNoCondition)869 TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition) {
870 auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
871
872 int64_t baseTimeNs = getElapsedRealtimeNs();
873 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
874 int64_t bucketSizeNs =
875 TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
876
877 ConfigKey cfgKey;
878 auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
879 SharedRefBase::make<FakeSubsystemSleepCallback>(),
880 ATOM_TAG);
881 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
882 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
883 processor->mPullerManager->ForceClearPullerCache();
884
885 int startBucketNum = processor->mMetricsManagers.begin()->second->
886 mAllMetricProducers[0]->getCurrentBucketNum();
887 EXPECT_GT(startBucketNum, (int64_t)0);
888
889 // When creating the config, the gauge metric producer should register the alarm at the
890 // end of the current bucket.
891 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
892 EXPECT_EQ(bucketSizeNs,
893 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
894 int64_t& nextPullTimeNs =
895 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
896 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
897
898 // Pulling alarm arrives on time and reset the sequential pulling alarm.
899 processor->informPullAlarmFired(nextPullTimeNs + 1);
900 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
901
902 processor->informPullAlarmFired(nextPullTimeNs + 4);
903 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
904 nextPullTimeNs);
905
906 ConfigMetricsReportList reports;
907 vector<uint8_t> buffer;
908 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
909 ADB_DUMP, FAST, &buffer);
910 EXPECT_TRUE(buffer.size() > 0);
911 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
912 backfillDimensionPath(&reports);
913 backfillStringInReport(&reports);
914 backfillStartEndTimestamp(&reports);
915 backfillAggregatedAtoms(&reports);
916 ASSERT_EQ(1, reports.reports_size());
917 ASSERT_EQ(1, reports.reports(0).metrics_size());
918 StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
919 sortMetricDataByDimensionsValue(
920 reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
921 ASSERT_GT((int)gaugeMetrics.data_size(), 0);
922
923 auto data = gaugeMetrics.data(0);
924 EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
925 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
926 EXPECT_EQ(1 /* subsystem name field */,
927 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
928 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
929 ASSERT_EQ(3, data.bucket_info_size());
930
931 ASSERT_EQ(1, data.bucket_info(0).atom_size());
932 ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
933 EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0));
934 ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
935 EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
936 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
937 EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
938 EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
939
940 ASSERT_EQ(1, data.bucket_info(1).atom_size());
941 ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
942 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
943 ASSERT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
944 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
945 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
946 EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
947 EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
948
949 ASSERT_EQ(1, data.bucket_info(2).atom_size());
950 ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
951 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0));
952 ASSERT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
953 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
954 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
955 EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
956 EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
957 }
958
959 #else
960 GTEST_LOG_(INFO) << "This test does nothing.\n";
961 #endif
962
963 } // namespace statsd
964 } // namespace os
965 } // namespace android
966