Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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 | |
| 23 | namespace android { |
| 24 | namespace os { |
| 25 | namespace statsd { |
| 26 | |
| 27 | #ifdef __ANDROID__ |
| 28 | |
| 29 | namespace { |
| 30 | |
| 31 | StatsdConfig 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 | |
| 57 | TEST(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()); |
Yangster-mac | 58e609e | 2018-05-08 16:10:32 -0700 | [diff] [blame] | 69 | processor->mStatsPullerManager.ForceClearPullerCache(); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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; |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 126 | processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, |
| 127 | ADB_DUMP, &buffer); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 128 | EXPECT_TRUE(buffer.size() > 0); |
| 129 | EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 130 | backfillDimensionPath(&reports); |
| 131 | backfillStringInReport(&reports); |
| 132 | backfillStartEndTimestamp(&reports); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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 | |
| 203 | TEST(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()); |
Yangster-mac | 58e609e | 2018-05-08 16:10:32 -0700 | [diff] [blame] | 215 | processor->mStatsPullerManager.ForceClearPullerCache(); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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; |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 249 | processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true, |
| 250 | ADB_DUMP, &buffer); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 251 | EXPECT_TRUE(buffer.size() > 0); |
| 252 | EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 253 | backfillDimensionPath(&reports); |
| 254 | backfillStringInReport(&reports); |
| 255 | backfillStartEndTimestamp(&reports); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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 | |
| 304 | TEST(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()); |
Yangster-mac | 58e609e | 2018-05-08 16:10:32 -0700 | [diff] [blame] | 316 | processor->mStatsPullerManager.ForceClearPullerCache(); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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; |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 354 | processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true, |
| 355 | ADB_DUMP, &buffer); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 356 | EXPECT_TRUE(buffer.size() > 0); |
| 357 | EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size())); |
Yangster-mac | 9def8e3 | 2018-04-17 13:55:51 -0700 | [diff] [blame] | 358 | backfillDimensionPath(&reports); |
| 359 | backfillStringInReport(&reports); |
| 360 | backfillStartEndTimestamp(&reports); |
Yangster-mac | 15f6bbc | 2018-04-08 11:52:26 -0700 | [diff] [blame] | 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 |
| 406 | GTEST_LOG_(INFO) << "This test does nothing.\n"; |
| 407 | #endif |
| 408 | |
| 409 | } // namespace statsd |
| 410 | } // namespace os |
| 411 | } // namespace android |