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_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
41     auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
42     *config.add_atom_matcher() = atomMatcher;
43     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
44     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
45 
46     auto screenIsOffPredicate = CreateScreenIsOffPredicate();
47     *config.add_predicate() = screenIsOffPredicate;
48 
49     auto gaugeMetric = config.add_gauge_metric();
50     gaugeMetric->set_id(metricId);
51     gaugeMetric->set_what(atomMatcher.id());
52     if (useCondition) {
53         gaugeMetric->set_condition(screenIsOffPredicate.id());
54     }
55     gaugeMetric->set_sampling_type(sampling_type);
56     gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
57     *gaugeMetric->mutable_dimensions_in_what() =
58             CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
59     gaugeMetric->set_bucket(FIVE_MINUTES);
60     gaugeMetric->set_max_pull_delay_sec(INT_MAX);
61     config.set_hash_strings_in_metric_report(false);
62     gaugeMetric->set_split_bucket_for_app_upgrade(true);
63     gaugeMetric->set_min_bucket_size_nanos(1000);
64 
65     return config;
66 }
67 
68 }  // namespaces
69 
TEST(GaugeMetricE2ePulledTest,TestRandomSamplePulledEvents)70 TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents) {
71     auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
72     int64_t baseTimeNs = getElapsedRealtimeNs();
73     int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
74     int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
75 
76     ConfigKey cfgKey;
77     auto processor =
78             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
79                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
80     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
81     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
82     processor->mPullerManager->ForceClearPullerCache();
83 
84     int startBucketNum = processor->mMetricsManagers.begin()
85                                  ->second->mAllMetricProducers[0]
86                                  ->getCurrentBucketNum();
87     EXPECT_GT(startBucketNum, (int64_t)0);
88 
89     // When creating the config, the gauge metric producer should register the alarm at the
90     // end of the current bucket.
91     ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
92     EXPECT_EQ(bucketSizeNs,
93               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
94     int64_t& nextPullTimeNs =
95             processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
96     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
97 
98     auto screenOffEvent =
99             CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
100     processor->OnLogEvent(screenOffEvent.get());
101 
102     // Pulling alarm arrives on time and reset the sequential pulling alarm.
103     processor->informPullAlarmFired(nextPullTimeNs + 1);
104     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
105 
106     auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
107                                                        android::view::DISPLAY_STATE_ON);
108     processor->OnLogEvent(screenOnEvent.get());
109 
110     screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
111                                                    android::view::DISPLAY_STATE_OFF);
112     processor->OnLogEvent(screenOffEvent.get());
113 
114     processor->informPullAlarmFired(nextPullTimeNs + 1);
115     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
116 
117     processor->informPullAlarmFired(nextPullTimeNs + 1);
118     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
119 
120     screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
121                                                   android::view::DISPLAY_STATE_ON);
122     processor->OnLogEvent(screenOnEvent.get());
123 
124     processor->informPullAlarmFired(nextPullTimeNs + 3);
125     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
126 
127     screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
128                                                    android::view::DISPLAY_STATE_OFF);
129     processor->OnLogEvent(screenOffEvent.get());
130 
131     processor->informPullAlarmFired(nextPullTimeNs + 2);
132     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
133 
134     processor->informPullAlarmFired(nextPullTimeNs + 2);
135 
136     ConfigMetricsReportList reports;
137     vector<uint8_t> buffer;
138     processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
139                             ADB_DUMP, FAST, &buffer);
140     EXPECT_TRUE(buffer.size() > 0);
141     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
142     backfillDimensionPath(&reports);
143     backfillStringInReport(&reports);
144     backfillStartEndTimestamp(&reports);
145     backfillAggregatedAtoms(&reports);
146     ASSERT_EQ(1, reports.reports_size());
147     ASSERT_EQ(1, reports.reports(0).metrics_size());
148     EXPECT_TRUE(reports.reports(0).metrics(0).has_estimated_data_bytes());
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 
TEST(GaugeMetricE2ePulledTest,TestGaugeMetricPullProbabilityWithTriggerEvent)959 TEST(GaugeMetricE2ePulledTest, TestGaugeMetricPullProbabilityWithTriggerEvent) {
960     // Initiating StatsdStats at the start of this test, so it doesn't call rand() during the test.
961     StatsdStats::getInstance();
962     // Set srand seed to make rand deterministic for testing.
963     srand(0);
964 
965     auto config = CreateStatsdConfig(GaugeMetric::FIRST_N_SAMPLES, /*useCondition=*/false);
966     auto gaugeMetric = config.mutable_gauge_metric(0);
967     gaugeMetric->set_pull_probability(50);
968     auto triggerEventMatcher = CreateScreenTurnedOnAtomMatcher();
969     gaugeMetric->set_trigger_event(triggerEventMatcher.id());
970     gaugeMetric->set_max_num_gauge_atoms_per_bucket(200);
971     gaugeMetric->set_bucket(ONE_HOUR);
972 
973     int64_t configAddedTimeNs = 60 * NS_PER_SEC;
974     int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
975 
976     ConfigKey cfgKey;
977     auto processor =
978             CreateStatsLogProcessor(configAddedTimeNs, configAddedTimeNs, config, cfgKey,
979                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
980 
981     std::vector<std::unique_ptr<LogEvent>> events;
982     // First bucket events.
983     for (int i = 0; i < 30; i++) {
984         events.push_back(CreateScreenStateChangedEvent(configAddedTimeNs + (i * 10 * NS_PER_SEC),
985                                                        android::view::DISPLAY_STATE_ON));
986     }
987     // Second bucket events.
988     for (int i = 0; i < 30; i++) {
989         events.push_back(CreateScreenStateChangedEvent(
990                 configAddedTimeNs + bucketSizeNs + (i * 10 * NS_PER_SEC),
991                 android::view::DISPLAY_STATE_ON));
992     }
993 
994     // Send log events to StatsLogProcessor.
995     for (auto& event : events) {
996         processor->OnLogEvent(event.get());
997     }
998 
999     ConfigMetricsReportList reports;
1000     vector<uint8_t> buffer;
1001     processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
1002                             ADB_DUMP, FAST, &buffer);
1003 
1004     EXPECT_TRUE(buffer.size() > 0);
1005     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1006     backfillDimensionPath(&reports);
1007     backfillStringInReport(&reports);
1008     backfillStartEndTimestamp(&reports);
1009     backfillAggregatedAtoms(&reports);
1010     ASSERT_EQ(1, reports.reports_size());
1011     ASSERT_EQ(1, reports.reports(0).metrics_size());
1012     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
1013     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
1014     ASSERT_EQ((int)gaugeMetrics.data_size(), 2);  // 2 sets of data for each pull.
1015 
1016     // Data 1
1017     auto data = gaugeMetrics.data(0);
1018     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1019     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1020     EXPECT_EQ(1 /* subsystem name field */,
1021               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1022     EXPECT_EQ("subsystem_name_1",
1023               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1024     ASSERT_EQ(2, data.bucket_info_size());
1025 
1026     // Data 1, Bucket 1
1027     ASSERT_EQ(13, data.bucket_info(0).atom_size());
1028     ValidateGaugeBucketTimes(
1029             data.bucket_info(0), configAddedTimeNs, configAddedTimeNs + bucketSizeNs,
1030             {(int64_t)60 * NS_PER_SEC, (int64_t)80 * NS_PER_SEC, (int64_t)90 * NS_PER_SEC,
1031              (int64_t)130 * NS_PER_SEC, (int64_t)150 * NS_PER_SEC, (int64_t)170 * NS_PER_SEC,
1032              (int64_t)190 * NS_PER_SEC, (int64_t)200 * NS_PER_SEC, (int64_t)240 * NS_PER_SEC,
1033              (int64_t)250 * NS_PER_SEC, (int64_t)300 * NS_PER_SEC, (int64_t)330 * NS_PER_SEC,
1034              (int64_t)340 * NS_PER_SEC});
1035 
1036     // Data 1, Bucket 2
1037     ASSERT_EQ(18, data.bucket_info(1).atom_size());
1038     ValidateGaugeBucketTimes(
1039             data.bucket_info(1), configAddedTimeNs + bucketSizeNs,
1040             configAddedTimeNs + 2 * bucketSizeNs,
1041             {(int64_t)3660 * NS_PER_SEC, (int64_t)3680 * NS_PER_SEC, (int64_t)3700 * NS_PER_SEC,
1042              (int64_t)3710 * NS_PER_SEC, (int64_t)3720 * NS_PER_SEC, (int64_t)3740 * NS_PER_SEC,
1043              (int64_t)3780 * NS_PER_SEC, (int64_t)3790 * NS_PER_SEC, (int64_t)3820 * NS_PER_SEC,
1044              (int64_t)3850 * NS_PER_SEC, (int64_t)3860 * NS_PER_SEC, (int64_t)3870 * NS_PER_SEC,
1045              (int64_t)3880 * NS_PER_SEC, (int64_t)3900 * NS_PER_SEC, (int64_t)3910 * NS_PER_SEC,
1046              (int64_t)3920 * NS_PER_SEC, (int64_t)3930 * NS_PER_SEC, (int64_t)3940 * NS_PER_SEC});
1047 
1048     // Data 2
1049     data = gaugeMetrics.data(1);
1050     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1051     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1052     EXPECT_EQ(1 /* subsystem name field */,
1053               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1054     EXPECT_EQ("subsystem_name_2",
1055               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1056     ASSERT_EQ(2, data.bucket_info_size());
1057 
1058     // Data 2, Bucket 1
1059     ASSERT_EQ(13, data.bucket_info(0).atom_size());
1060     ValidateGaugeBucketTimes(
1061             data.bucket_info(0), configAddedTimeNs, configAddedTimeNs + bucketSizeNs,
1062             {(int64_t)60 * NS_PER_SEC, (int64_t)80 * NS_PER_SEC, (int64_t)90 * NS_PER_SEC,
1063              (int64_t)130 * NS_PER_SEC, (int64_t)150 * NS_PER_SEC, (int64_t)170 * NS_PER_SEC,
1064              (int64_t)190 * NS_PER_SEC, (int64_t)200 * NS_PER_SEC, (int64_t)240 * NS_PER_SEC,
1065              (int64_t)250 * NS_PER_SEC, (int64_t)300 * NS_PER_SEC, (int64_t)330 * NS_PER_SEC,
1066              (int64_t)340 * NS_PER_SEC});
1067 
1068     // Data 2, Bucket 2
1069     ASSERT_EQ(18, data.bucket_info(1).atom_size());
1070     ValidateGaugeBucketTimes(
1071             data.bucket_info(1), configAddedTimeNs + bucketSizeNs,
1072             configAddedTimeNs + 2 * bucketSizeNs,
1073             {(int64_t)3660 * NS_PER_SEC, (int64_t)3680 * NS_PER_SEC, (int64_t)3700 * NS_PER_SEC,
1074              (int64_t)3710 * NS_PER_SEC, (int64_t)3720 * NS_PER_SEC, (int64_t)3740 * NS_PER_SEC,
1075              (int64_t)3780 * NS_PER_SEC, (int64_t)3790 * NS_PER_SEC, (int64_t)3820 * NS_PER_SEC,
1076              (int64_t)3850 * NS_PER_SEC, (int64_t)3860 * NS_PER_SEC, (int64_t)3870 * NS_PER_SEC,
1077              (int64_t)3880 * NS_PER_SEC, (int64_t)3900 * NS_PER_SEC, (int64_t)3910 * NS_PER_SEC,
1078              (int64_t)3920 * NS_PER_SEC, (int64_t)3930 * NS_PER_SEC, (int64_t)3940 * NS_PER_SEC});
1079 }
1080 
TEST(GaugeMetricE2ePulledTest,TestGaugeMetricPullProbabilityWithBucketBoundaryAlarm)1081 TEST(GaugeMetricE2ePulledTest, TestGaugeMetricPullProbabilityWithBucketBoundaryAlarm) {
1082     // Initiating StatsdStats at the start of this test, so it doesn't call rand() during the test.
1083     StatsdStats::getInstance();
1084     // Set srand seed to make rand deterministic for testing.
1085     srand(0);
1086 
1087     auto config = CreateStatsdConfig(GaugeMetric::FIRST_N_SAMPLES, /*useCondition=*/false);
1088     auto gaugeMetric = config.mutable_gauge_metric(0);
1089     gaugeMetric->set_pull_probability(50);
1090     gaugeMetric->set_max_num_gauge_atoms_per_bucket(200);
1091 
1092     int64_t baseTimeNs = 5 * 60 * NS_PER_SEC;
1093     int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC;
1094     int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
1095 
1096     ConfigKey cfgKey;
1097     auto processor =
1098             CreateStatsLogProcessor(configAddedTimeNs, configAddedTimeNs, config, cfgKey,
1099                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
1100 
1101     // Pulling alarm arrives on time and resets the sequential pulling alarm.
1102     for (int i = 1; i < 31; i++) {
1103         processor->informPullAlarmFired(configAddedTimeNs + i * bucketSizeNs);
1104     }
1105 
1106     ConfigMetricsReportList reports;
1107     vector<uint8_t> buffer;
1108     processor->onDumpReport(cfgKey, configAddedTimeNs + 32 * bucketSizeNs + 10, false, true,
1109                             ADB_DUMP, FAST, &buffer);
1110     EXPECT_TRUE(buffer.size() > 0);
1111     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1112     backfillDimensionPath(&reports);
1113     backfillStringInReport(&reports);
1114     backfillStartEndTimestamp(&reports);
1115     backfillAggregatedAtoms(&reports);
1116     ASSERT_EQ(1, reports.reports_size());
1117     ASSERT_EQ(1, reports.reports(0).metrics_size());
1118     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
1119     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
1120     ASSERT_EQ((int)gaugeMetrics.data_size(), 2);
1121 
1122     // Data 1
1123     auto data = gaugeMetrics.data(0);
1124     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1125     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1126     EXPECT_EQ(1 /* subsystem name field */,
1127               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1128     EXPECT_EQ("subsystem_name_1",
1129               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1130     ASSERT_EQ(14, data.bucket_info_size());
1131 
1132     EXPECT_EQ(1, data.bucket_info(0).atom_size());
1133     ValidateGaugeBucketTimes(data.bucket_info(0), configAddedTimeNs,
1134                              configAddedTimeNs + bucketSizeNs, {configAddedTimeNs});
1135 
1136     EXPECT_EQ(1, data.bucket_info(1).atom_size());
1137     ValidateGaugeBucketTimes(data.bucket_info(1), configAddedTimeNs + 2 * bucketSizeNs,
1138                              configAddedTimeNs + 3 * bucketSizeNs,
1139                              {configAddedTimeNs + 2 * bucketSizeNs});  // 1200000000000ns
1140 
1141     EXPECT_EQ(1, data.bucket_info(2).atom_size());
1142     ValidateGaugeBucketTimes(data.bucket_info(2), configAddedTimeNs + 3 * bucketSizeNs,
1143                              configAddedTimeNs + 4 * bucketSizeNs,
1144                              {(int64_t)configAddedTimeNs + 3 * bucketSizeNs});  // 1500000000000ns
1145 
1146     EXPECT_EQ(1, data.bucket_info(3).atom_size());
1147     ValidateGaugeBucketTimes(data.bucket_info(3), configAddedTimeNs + 7 * bucketSizeNs,
1148                              configAddedTimeNs + 8 * bucketSizeNs,
1149                              {configAddedTimeNs + 7 * bucketSizeNs});  // 2700000000000ns
1150 
1151     EXPECT_EQ(1, data.bucket_info(4).atom_size());
1152     ValidateGaugeBucketTimes(data.bucket_info(4), configAddedTimeNs + 9 * bucketSizeNs,
1153                              configAddedTimeNs + 10 * bucketSizeNs,
1154                              {configAddedTimeNs + 9 * bucketSizeNs});  // 3300000000000ns
1155 
1156     EXPECT_EQ(1, data.bucket_info(5).atom_size());
1157     ValidateGaugeBucketTimes(data.bucket_info(5), configAddedTimeNs + 11 * bucketSizeNs,
1158                              configAddedTimeNs + 12 * bucketSizeNs,
1159                              {configAddedTimeNs + 11 * bucketSizeNs});  // 3900000000000ns
1160 
1161     EXPECT_EQ(1, data.bucket_info(6).atom_size());
1162     ValidateGaugeBucketTimes(data.bucket_info(6), configAddedTimeNs + 13 * bucketSizeNs,
1163                              configAddedTimeNs + 14 * bucketSizeNs,
1164                              {configAddedTimeNs + 13 * bucketSizeNs});  // 4500000000000ns
1165 
1166     EXPECT_EQ(1, data.bucket_info(7).atom_size());
1167     ValidateGaugeBucketTimes(data.bucket_info(7), configAddedTimeNs + 14 * bucketSizeNs,
1168                              configAddedTimeNs + 15 * bucketSizeNs,
1169                              {configAddedTimeNs + 14 * bucketSizeNs});  // 4800000000000ns
1170 
1171     EXPECT_EQ(1, data.bucket_info(8).atom_size());
1172     ValidateGaugeBucketTimes(data.bucket_info(8), configAddedTimeNs + 18 * bucketSizeNs,
1173                              configAddedTimeNs + 19 * bucketSizeNs,
1174                              {configAddedTimeNs + 18 * bucketSizeNs});  // 6000000000000ns
1175 
1176     EXPECT_EQ(1, data.bucket_info(9).atom_size());
1177     ValidateGaugeBucketTimes(data.bucket_info(9), configAddedTimeNs + 19 * bucketSizeNs,
1178                              configAddedTimeNs + 20 * bucketSizeNs,
1179                              {configAddedTimeNs + 19 * bucketSizeNs});  // 6300000000000ns
1180 
1181     EXPECT_EQ(1, data.bucket_info(10).atom_size());
1182     ValidateGaugeBucketTimes(data.bucket_info(10), configAddedTimeNs + 24 * bucketSizeNs,
1183                              configAddedTimeNs + 25 * bucketSizeNs,
1184                              {configAddedTimeNs + 24 * bucketSizeNs});  // 7800000000000ns
1185 
1186     EXPECT_EQ(1, data.bucket_info(11).atom_size());
1187     ValidateGaugeBucketTimes(data.bucket_info(11), configAddedTimeNs + 27 * bucketSizeNs,
1188                              configAddedTimeNs + 28 * bucketSizeNs,
1189                              {configAddedTimeNs + 27 * bucketSizeNs});  // 8700000000000ns
1190 
1191     EXPECT_EQ(1, data.bucket_info(12).atom_size());
1192     ValidateGaugeBucketTimes(data.bucket_info(12), configAddedTimeNs + 28 * bucketSizeNs,
1193                              configAddedTimeNs + 29 * bucketSizeNs,
1194                              {configAddedTimeNs + 28 * bucketSizeNs});  // 9000000000000ns
1195 
1196     EXPECT_EQ(1, data.bucket_info(13).atom_size());
1197     ValidateGaugeBucketTimes(data.bucket_info(13), configAddedTimeNs + 30 * bucketSizeNs,
1198                              configAddedTimeNs + 31 * bucketSizeNs,
1199                              {configAddedTimeNs + 30 * bucketSizeNs});  // 9600000000000ns
1200 
1201     // Data 2
1202     data = gaugeMetrics.data(1);
1203     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1204     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1205     EXPECT_EQ(1 /* subsystem name field */,
1206               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1207     EXPECT_EQ("subsystem_name_2",
1208               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1209     ASSERT_EQ(14, data.bucket_info_size());
1210 
1211     EXPECT_EQ(1, data.bucket_info(0).atom_size());
1212     ValidateGaugeBucketTimes(data.bucket_info(0), configAddedTimeNs,
1213                              configAddedTimeNs + bucketSizeNs, {configAddedTimeNs});
1214 
1215     EXPECT_EQ(1, data.bucket_info(1).atom_size());
1216     ValidateGaugeBucketTimes(data.bucket_info(1), configAddedTimeNs + 2 * bucketSizeNs,
1217                              configAddedTimeNs + 3 * bucketSizeNs,
1218                              {configAddedTimeNs + 2 * bucketSizeNs});
1219 
1220     EXPECT_EQ(1, data.bucket_info(2).atom_size());
1221     ValidateGaugeBucketTimes(data.bucket_info(2), configAddedTimeNs + 3 * bucketSizeNs,
1222                              configAddedTimeNs + 4 * bucketSizeNs,
1223                              {(int64_t)configAddedTimeNs + 3 * bucketSizeNs});
1224 
1225     EXPECT_EQ(1, data.bucket_info(3).atom_size());
1226     ValidateGaugeBucketTimes(data.bucket_info(3), configAddedTimeNs + 7 * bucketSizeNs,
1227                              configAddedTimeNs + 8 * bucketSizeNs,
1228                              {configAddedTimeNs + 7 * bucketSizeNs});
1229 
1230     EXPECT_EQ(1, data.bucket_info(4).atom_size());
1231     ValidateGaugeBucketTimes(data.bucket_info(4), configAddedTimeNs + 9 * bucketSizeNs,
1232                              configAddedTimeNs + 10 * bucketSizeNs,
1233                              {configAddedTimeNs + 9 * bucketSizeNs});
1234 
1235     EXPECT_EQ(1, data.bucket_info(5).atom_size());
1236     ValidateGaugeBucketTimes(data.bucket_info(5), configAddedTimeNs + 11 * bucketSizeNs,
1237                              configAddedTimeNs + 12 * bucketSizeNs,
1238                              {configAddedTimeNs + 11 * bucketSizeNs});
1239 
1240     EXPECT_EQ(1, data.bucket_info(6).atom_size());
1241     ValidateGaugeBucketTimes(data.bucket_info(6), configAddedTimeNs + 13 * bucketSizeNs,
1242                              configAddedTimeNs + 14 * bucketSizeNs,
1243                              {configAddedTimeNs + 13 * bucketSizeNs});
1244 
1245     EXPECT_EQ(1, data.bucket_info(7).atom_size());
1246     ValidateGaugeBucketTimes(data.bucket_info(7), configAddedTimeNs + 14 * bucketSizeNs,
1247                              configAddedTimeNs + 15 * bucketSizeNs,
1248                              {configAddedTimeNs + 14 * bucketSizeNs});
1249 
1250     EXPECT_EQ(1, data.bucket_info(8).atom_size());
1251     ValidateGaugeBucketTimes(data.bucket_info(8), configAddedTimeNs + 18 * bucketSizeNs,
1252                              configAddedTimeNs + 19 * bucketSizeNs,
1253                              {configAddedTimeNs + 18 * bucketSizeNs});
1254 
1255     EXPECT_EQ(1, data.bucket_info(9).atom_size());
1256     ValidateGaugeBucketTimes(data.bucket_info(9), configAddedTimeNs + 19 * bucketSizeNs,
1257                              configAddedTimeNs + 20 * bucketSizeNs,
1258                              {configAddedTimeNs + 19 * bucketSizeNs});
1259 
1260     EXPECT_EQ(1, data.bucket_info(10).atom_size());
1261     ValidateGaugeBucketTimes(data.bucket_info(10), configAddedTimeNs + 24 * bucketSizeNs,
1262                              configAddedTimeNs + 25 * bucketSizeNs,
1263                              {configAddedTimeNs + 24 * bucketSizeNs});
1264 
1265     EXPECT_EQ(1, data.bucket_info(11).atom_size());
1266     ValidateGaugeBucketTimes(data.bucket_info(11), configAddedTimeNs + 27 * bucketSizeNs,
1267                              configAddedTimeNs + 28 * bucketSizeNs,
1268                              {configAddedTimeNs + 27 * bucketSizeNs});
1269 
1270     EXPECT_EQ(1, data.bucket_info(12).atom_size());
1271     ValidateGaugeBucketTimes(data.bucket_info(12), configAddedTimeNs + 28 * bucketSizeNs,
1272                              configAddedTimeNs + 29 * bucketSizeNs,
1273                              {configAddedTimeNs + 28 * bucketSizeNs});
1274 
1275     EXPECT_EQ(1, data.bucket_info(13).atom_size());
1276     ValidateGaugeBucketTimes(data.bucket_info(13), configAddedTimeNs + 30 * bucketSizeNs,
1277                              configAddedTimeNs + 31 * bucketSizeNs,
1278                              {configAddedTimeNs + 30 * bucketSizeNs});
1279 }
1280 
TEST(GaugeMetricE2ePulledTest,TestGaugeMetricPullProbabilityWithCondition)1281 TEST(GaugeMetricE2ePulledTest, TestGaugeMetricPullProbabilityWithCondition) {
1282     // Initiating StatsdStats at the start of this test, so it doesn't call rand() during the test.
1283     StatsdStats::getInstance();
1284     // Set srand seed to make rand deterministic for testing.
1285     srand(0);
1286 
1287     auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE, /*useCondition=*/true);
1288     auto gaugeMetric = config.mutable_gauge_metric(0);
1289     gaugeMetric->set_pull_probability(50);
1290     gaugeMetric->set_max_num_gauge_atoms_per_bucket(200);
1291     gaugeMetric->set_bucket(ONE_HOUR);
1292 
1293     int64_t configAddedTimeNs = 60 * NS_PER_SEC;
1294     int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
1295 
1296     ConfigKey cfgKey;
1297     auto processor =
1298             CreateStatsLogProcessor(configAddedTimeNs, configAddedTimeNs, config, cfgKey,
1299                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
1300 
1301     std::vector<std::unique_ptr<LogEvent>> events;
1302     // First bucket events.
1303     for (int i = 0; i < 30; i++) {
1304         events.push_back(CreateScreenStateChangedEvent(configAddedTimeNs + (i * 10 * NS_PER_SEC),
1305                                                        android::view::DISPLAY_STATE_OFF));
1306         events.push_back(CreateScreenStateChangedEvent(configAddedTimeNs + (i * 11 * NS_PER_SEC),
1307                                                        android::view::DISPLAY_STATE_ON));
1308     }
1309 
1310     // Send log events to StatsLogProcessor.
1311     for (auto& event : events) {
1312         processor->OnLogEvent(event.get());
1313     }
1314 
1315     ConfigMetricsReportList reports;
1316     vector<uint8_t> buffer;
1317     processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs, false, true, ADB_DUMP,
1318                             FAST, &buffer);
1319 
1320     EXPECT_TRUE(buffer.size() > 0);
1321     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1322     backfillDimensionPath(&reports);
1323     backfillStringInReport(&reports);
1324     backfillStartEndTimestamp(&reports);
1325     backfillAggregatedAtoms(&reports);
1326     ASSERT_EQ(1, reports.reports_size());
1327     ASSERT_EQ(1, reports.reports(0).metrics_size());
1328     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
1329     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
1330     ASSERT_EQ((int)gaugeMetrics.data_size(), 2);  // 2 sets of data for each pull.
1331 
1332     // Data 1
1333     auto data = gaugeMetrics.data(0);
1334     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1335     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1336     EXPECT_EQ(1 /* subsystem name field */,
1337               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1338     EXPECT_EQ("subsystem_name_1",
1339               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1340     ASSERT_EQ(1, data.bucket_info_size());
1341 
1342     // Data 1, Bucket 1
1343     ASSERT_EQ(13, data.bucket_info(0).atom_size());
1344     ValidateGaugeBucketTimes(
1345             data.bucket_info(0), configAddedTimeNs, configAddedTimeNs + bucketSizeNs,
1346             {(int64_t)60 * NS_PER_SEC, (int64_t)80 * NS_PER_SEC, (int64_t)90 * NS_PER_SEC,
1347              (int64_t)130 * NS_PER_SEC, (int64_t)150 * NS_PER_SEC, (int64_t)170 * NS_PER_SEC,
1348              (int64_t)190 * NS_PER_SEC, (int64_t)200 * NS_PER_SEC, (int64_t)240 * NS_PER_SEC,
1349              (int64_t)250 * NS_PER_SEC, (int64_t)300 * NS_PER_SEC, (int64_t)330 * NS_PER_SEC,
1350              (int64_t)340 * NS_PER_SEC});
1351 
1352     // Data 2
1353     data = gaugeMetrics.data(1);
1354     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
1355     ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
1356     EXPECT_EQ(1 /* subsystem name field */,
1357               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
1358     EXPECT_EQ("subsystem_name_2",
1359               data.dimensions_in_what().value_tuple().dimensions_value(0).value_str());
1360     ASSERT_EQ(1, data.bucket_info_size());
1361 
1362     // Data 2, Bucket 1
1363     ASSERT_EQ(13, data.bucket_info(0).atom_size());
1364     ValidateGaugeBucketTimes(
1365             data.bucket_info(0), configAddedTimeNs, configAddedTimeNs + bucketSizeNs,
1366             {(int64_t)60 * NS_PER_SEC, (int64_t)80 * NS_PER_SEC, (int64_t)90 * NS_PER_SEC,
1367              (int64_t)130 * NS_PER_SEC, (int64_t)150 * NS_PER_SEC, (int64_t)170 * NS_PER_SEC,
1368              (int64_t)190 * NS_PER_SEC, (int64_t)200 * NS_PER_SEC, (int64_t)240 * NS_PER_SEC,
1369              (int64_t)250 * NS_PER_SEC, (int64_t)300 * NS_PER_SEC, (int64_t)330 * NS_PER_SEC,
1370              (int64_t)340 * NS_PER_SEC});
1371 }
1372 
1373 #else
1374 GTEST_LOG_(INFO) << "This test does nothing.\n";
1375 #endif
1376 
1377 }  // namespace statsd
1378 }  // namespace os
1379 }  // namespace android
1380