1// Copyright (C) 2017 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <gtest/gtest.h>
16
17#include "src/StatsLogProcessor.h"
18#include "src/stats_log_util.h"
19#include "tests/statsd_test_util.h"
20
21#include <vector>
22
23namespace android {
24namespace os {
25namespace statsd {
26
27#ifdef __ANDROID__
28
29namespace {
30
31StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type) {
32    StatsdConfig config;
33    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
34    auto temperatureAtomMatcher = CreateTemperatureAtomMatcher();
35    *config.add_atom_matcher() = temperatureAtomMatcher;
36    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
37    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
38
39    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
40    *config.add_predicate() = screenIsOffPredicate;
41
42    auto gaugeMetric = config.add_gauge_metric();
43    gaugeMetric->set_id(123456);
44    gaugeMetric->set_what(temperatureAtomMatcher.id());
45    gaugeMetric->set_condition(screenIsOffPredicate.id());
46    gaugeMetric->set_sampling_type(sampling_type);
47    gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
48    *gaugeMetric->mutable_dimensions_in_what() =
49        CreateDimensions(android::util::TEMPERATURE, {2/* sensor name field */ });
50    gaugeMetric->set_bucket(FIVE_MINUTES);
51
52    return config;
53}
54
55}  // namespace
56
57TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
58    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
59    int64_t baseTimeNs = 10 * NS_PER_SEC;
60    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
61    int64_t bucketSizeNs =
62        TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
63
64    ConfigKey cfgKey;
65    auto processor = CreateStatsLogProcessor(
66        baseTimeNs, configAddedTimeNs, config, cfgKey);
67    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
68    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
69    processor->mStatsPullerManager.ForceClearPullerCache();
70
71    int startBucketNum = processor->mMetricsManagers.begin()->second->
72            mAllMetricProducers[0]->getCurrentBucketNum();
73    EXPECT_GT(startBucketNum, (int64_t)0);
74
75    // When creating the config, the gauge metric producer should register the alarm at the
76    // end of the current bucket.
77    EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size());
78    EXPECT_EQ(bucketSizeNs,
79              StatsPullerManagerImpl::GetInstance().mReceivers.begin()->
80                    second.front().intervalNs);
81    int64_t& nextPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()->
82            second.front().nextPullTimeNs;
83    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
84
85    auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
86                                                        configAddedTimeNs + 55);
87    processor->OnLogEvent(screenOffEvent.get());
88
89    // Pulling alarm arrives on time and reset the sequential pulling alarm.
90    processor->informPullAlarmFired(nextPullTimeNs + 1);
91    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
92
93    auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
94                                                       configAddedTimeNs + bucketSizeNs + 10);
95    processor->OnLogEvent(screenOnEvent.get());
96
97    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
98                                                   configAddedTimeNs + bucketSizeNs + 100);
99    processor->OnLogEvent(screenOffEvent.get());
100
101    processor->informPullAlarmFired(nextPullTimeNs + 1);
102    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
103              nextPullTimeNs);
104
105    processor->informPullAlarmFired(nextPullTimeNs + 1);
106    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
107
108    screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
109                                                  configAddedTimeNs + 3 * bucketSizeNs + 2);
110    processor->OnLogEvent(screenOnEvent.get());
111
112    processor->informPullAlarmFired(nextPullTimeNs + 3);
113    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
114
115    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
116                                                  configAddedTimeNs + 5 * bucketSizeNs + 1);
117    processor->OnLogEvent(screenOffEvent.get());
118
119    processor->informPullAlarmFired(nextPullTimeNs + 2);
120    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
121
122    processor->informPullAlarmFired(nextPullTimeNs + 2);
123
124    ConfigMetricsReportList reports;
125    vector<uint8_t> buffer;
126    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
127                            &buffer);
128    EXPECT_TRUE(buffer.size() > 0);
129    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
130    backfillDimensionPath(&reports);
131    backfillStringInReport(&reports);
132    backfillStartEndTimestamp(&reports);
133    EXPECT_EQ(1, reports.reports_size());
134    EXPECT_EQ(1, reports.reports(0).metrics_size());
135    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
136    sortMetricDataByDimensionsValue(
137            reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
138    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
139
140    auto data = gaugeMetrics.data(0);
141    EXPECT_EQ(android::util::TEMPERATURE, data.dimensions_in_what().field());
142    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
143    EXPECT_EQ(2 /* sensor name field */,
144              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
145    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
146    EXPECT_EQ(6, data.bucket_info_size());
147
148    EXPECT_EQ(1, data.bucket_info(0).atom_size());
149    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
150    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
151    EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
152    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
153    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
154    EXPECT_FALSE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
155    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
156
157    EXPECT_EQ(1, data.bucket_info(1).atom_size());
158    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1,
159              data.bucket_info(1).elapsed_timestamp_nanos(0));
160    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
161    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
162    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
163    EXPECT_FALSE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
164    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
165
166    EXPECT_EQ(1, data.bucket_info(2).atom_size());
167    EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
168    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1,
169              data.bucket_info(2).elapsed_timestamp_nanos(0));
170    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
171    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
172    EXPECT_FALSE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
173    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
174
175    EXPECT_EQ(1, data.bucket_info(3).atom_size());
176    EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
177    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1,
178              data.bucket_info(3).elapsed_timestamp_nanos(0));
179    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
180    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
181    EXPECT_FALSE(data.bucket_info(3).atom(0).temperature().sensor_name().empty());
182    EXPECT_GT(data.bucket_info(3).atom(0).temperature().temperature_dc(), 0);
183
184    EXPECT_EQ(1, data.bucket_info(4).atom_size());
185    EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
186    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1,
187              data.bucket_info(4).elapsed_timestamp_nanos(0));
188    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
189    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
190    EXPECT_FALSE(data.bucket_info(4).atom(0).temperature().sensor_name().empty());
191    EXPECT_GT(data.bucket_info(4).atom(0).temperature().temperature_dc(), 0);
192
193    EXPECT_EQ(1, data.bucket_info(5).atom_size());
194    EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
195    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2,
196              data.bucket_info(5).elapsed_timestamp_nanos(0));
197    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
198    EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
199    EXPECT_FALSE(data.bucket_info(5).atom(0).temperature().sensor_name().empty());
200    EXPECT_GT(data.bucket_info(5).atom(0).temperature().temperature_dc(), 0);
201}
202
203TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents) {
204    auto config = CreateStatsdConfig(GaugeMetric::ALL_CONDITION_CHANGES);
205    int64_t baseTimeNs = 10 * NS_PER_SEC;
206    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
207    int64_t bucketSizeNs =
208        TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
209
210    ConfigKey cfgKey;
211    auto processor = CreateStatsLogProcessor(
212        baseTimeNs, configAddedTimeNs, config, cfgKey);
213    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
214    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
215    processor->mStatsPullerManager.ForceClearPullerCache();
216
217    int startBucketNum = processor->mMetricsManagers.begin()->second->
218            mAllMetricProducers[0]->getCurrentBucketNum();
219    EXPECT_GT(startBucketNum, (int64_t)0);
220
221    auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
222                                                        configAddedTimeNs + 55);
223    processor->OnLogEvent(screenOffEvent.get());
224
225    auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
226                                                       configAddedTimeNs + bucketSizeNs + 10);
227    processor->OnLogEvent(screenOnEvent.get());
228
229    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
230                                                   configAddedTimeNs + bucketSizeNs + 100);
231    processor->OnLogEvent(screenOffEvent.get());
232
233    screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
234                                                  configAddedTimeNs + 3 * bucketSizeNs + 2);
235    processor->OnLogEvent(screenOnEvent.get());
236
237    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
238                                                  configAddedTimeNs + 5 * bucketSizeNs + 1);
239    processor->OnLogEvent(screenOffEvent.get());
240    screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
241                                                  configAddedTimeNs + 5 * bucketSizeNs + 3);
242    processor->OnLogEvent(screenOnEvent.get());
243    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
244                                                  configAddedTimeNs + 5 * bucketSizeNs + 10);
245    processor->OnLogEvent(screenOffEvent.get());
246
247    ConfigMetricsReportList reports;
248    vector<uint8_t> buffer;
249    processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, ADB_DUMP,
250                            &buffer);
251    EXPECT_TRUE(buffer.size() > 0);
252    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
253    backfillDimensionPath(&reports);
254    backfillStringInReport(&reports);
255    backfillStartEndTimestamp(&reports);
256    EXPECT_EQ(1, reports.reports_size());
257    EXPECT_EQ(1, reports.reports(0).metrics_size());
258    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
259    sortMetricDataByDimensionsValue(
260            reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
261    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
262
263    auto data = gaugeMetrics.data(0);
264    EXPECT_EQ(android::util::TEMPERATURE, data.dimensions_in_what().field());
265    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
266    EXPECT_EQ(2 /* sensor name field */,
267              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
268    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
269    EXPECT_EQ(3, data.bucket_info_size());
270
271    EXPECT_EQ(1, data.bucket_info(0).atom_size());
272    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
273    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
274    EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
275    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
276    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
277    EXPECT_FALSE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
278    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
279
280    EXPECT_EQ(1, data.bucket_info(1).atom_size());
281    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100,
282              data.bucket_info(1).elapsed_timestamp_nanos(0));
283    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
284    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
285    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
286    EXPECT_FALSE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
287    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
288
289    EXPECT_EQ(2, data.bucket_info(2).atom_size());
290    EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
291    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1,
292              data.bucket_info(2).elapsed_timestamp_nanos(0));
293    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10,
294              data.bucket_info(2).elapsed_timestamp_nanos(1));
295    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
296    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
297    EXPECT_FALSE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
298    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
299    EXPECT_FALSE(data.bucket_info(2).atom(1).temperature().sensor_name().empty());
300    EXPECT_GT(data.bucket_info(2).atom(1).temperature().temperature_dc(), 0);
301}
302
303
304TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
305    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
306    int64_t baseTimeNs = 10 * NS_PER_SEC;
307    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
308    int64_t bucketSizeNs =
309        TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
310
311    ConfigKey cfgKey;
312    auto processor = CreateStatsLogProcessor(
313        baseTimeNs, configAddedTimeNs, config, cfgKey);
314    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
315    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
316    processor->mStatsPullerManager.ForceClearPullerCache();
317
318    int startBucketNum = processor->mMetricsManagers.begin()->second->
319            mAllMetricProducers[0]->getCurrentBucketNum();
320    EXPECT_GT(startBucketNum, (int64_t)0);
321
322    // When creating the config, the gauge metric producer should register the alarm at the
323    // end of the current bucket.
324    EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size());
325    EXPECT_EQ(bucketSizeNs,
326              StatsPullerManagerImpl::GetInstance().mReceivers.begin()->
327                    second.front().intervalNs);
328    int64_t& nextPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()->
329            second.front().nextPullTimeNs;
330    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
331
332    auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
333                                                        configAddedTimeNs + 55);
334    processor->OnLogEvent(screenOffEvent.get());
335
336    auto screenOnEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
337                                                       configAddedTimeNs + bucketSizeNs + 10);
338    processor->OnLogEvent(screenOnEvent.get());
339
340    // Pulling alarm arrives one bucket size late.
341    processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
342    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
343
344    screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
345                                                   configAddedTimeNs + 3 * bucketSizeNs + 11);
346    processor->OnLogEvent(screenOffEvent.get());
347
348    // Pulling alarm arrives more than one bucket size late.
349    processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
350    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
351
352    ConfigMetricsReportList reports;
353    vector<uint8_t> buffer;
354    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
355                            &buffer);
356    EXPECT_TRUE(buffer.size() > 0);
357    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
358    backfillDimensionPath(&reports);
359    backfillStringInReport(&reports);
360    backfillStartEndTimestamp(&reports);
361    EXPECT_EQ(1, reports.reports_size());
362    EXPECT_EQ(1, reports.reports(0).metrics_size());
363    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
364    sortMetricDataByDimensionsValue(
365            reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
366    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
367
368    auto data = gaugeMetrics.data(0);
369    EXPECT_EQ(android::util::TEMPERATURE, data.dimensions_in_what().field());
370    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
371    EXPECT_EQ(2 /* sensor name field */,
372              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
373    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
374    EXPECT_EQ(3, data.bucket_info_size());
375
376    EXPECT_EQ(1, data.bucket_info(0).atom_size());
377    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
378    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
379    EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
380    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
381    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
382    EXPECT_FALSE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
383    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
384
385    EXPECT_EQ(1, data.bucket_info(1).atom_size());
386    EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
387              data.bucket_info(1).elapsed_timestamp_nanos(0));
388    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
389    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
390    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
391    EXPECT_FALSE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
392    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
393
394    EXPECT_EQ(1, data.bucket_info(2).atom_size());
395    EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
396    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12,
397              data.bucket_info(2).elapsed_timestamp_nanos(0));
398    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
399    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
400    EXPECT_FALSE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
401    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
402
403}
404
405#else
406GTEST_LOG_(INFO) << "This test does nothing.\n";
407#endif
408
409}  // namespace statsd
410}  // namespace os
411}  // namespace android
412